Skip to content

Commit 3d03320

Browse files
committed
Merge pull request #37 from zerth/adjust-ext-type-code-check
Adjust ext type code handling to match spec
2 parents 3cdc3ad + 0f90a3a commit 3d03320

File tree

4 files changed

+48
-18
lines changed

4 files changed

+48
-18
lines changed

src/msgpack_packer.erl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -374,19 +374,19 @@ pack_map(M, Opt)->
374374
-spec pack_ext(any(), msgpack_ext_packer(), msgpack:options()) -> {ok, binary()} | {error, any()}.
375375
pack_ext(Any, Packer, Opt) ->
376376
case Packer(Any, Opt) of
377-
{ok, {Type, Data}} when 0 < Type andalso Type < 16#100 ->
377+
{ok, {Type, Data}} when -16#80 =< Type andalso Type =< 16#7F ->
378378
Bin = case byte_size(Data) of
379-
1 -> <<16#D4, Type:8, Data/binary>>;
380-
2 -> <<16#D5, Type:8, Data/binary>>;
381-
4 -> <<16#D6, Type:8, Data/binary>>;
382-
8 -> <<16#D7, Type:8, Data/binary>>;
383-
16 -> <<16#D8, Type:8, Data/binary>>;
379+
1 -> <<16#D4, Type:1/signed-integer-unit:8, Data/binary>>;
380+
2 -> <<16#D5, Type:1/signed-integer-unit:8, Data/binary>>;
381+
4 -> <<16#D6, Type:1/signed-integer-unit:8, Data/binary>>;
382+
8 -> <<16#D7, Type:1/signed-integer-unit:8, Data/binary>>;
383+
16 -> <<16#D8, Type:1/signed-integer-unit:8, Data/binary>>;
384384
Len when Len < 16#100 ->
385-
<<16#C7, Len:8, Type:8, Data/binary>>;
385+
<<16#C7, Len:8, Type:1/signed-integer-unit:8, Data/binary>>;
386386
Len when Len < 16#10000 ->
387-
<<16#C8, Len:16, Type:8, Data/binary>>;
387+
<<16#C8, Len:16, Type:1/signed-integer-unit:8, Data/binary>>;
388388
Len when Len < 16#100000000 ->
389-
<<16#C9, Len:32, Type:8, Data/binary>>
389+
<<16#C9, Len:32, Type:1/signed-integer-unit:8, Data/binary>>
390390
end,
391391
{ok, Bin};
392392
{error, E} ->

src/msgpack_term.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
pack_ext/2, unpack_ext/3]).
2222
-behaviour(msgpack_ext).
2323

24-
-define(ERLANG_TERM, 131).
24+
-define(ERLANG_TERM, 127).
2525
-define(TERM_OPTION, [{enable_str,true},{ext,?MODULE},{allow_atom,none}]).
2626

2727
%% @doc experimental

src/msgpack_unpacker.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,42 +126,42 @@ unpack_stream(<<16#C1, _R/binary>>, _) -> throw({badarg, 16#C1});
126126
%% for extention types
127127

128128
%% fixext 1 stores an integer and a byte array whose length is 1 byte
129-
unpack_stream(<<16#D4, T:8, Data:1/binary, Rest/binary>>,
129+
unpack_stream(<<16#D4, T:1/signed-integer-unit:8, Data:1/binary, Rest/binary>>,
130130
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
131131
maybe_unpack_ext(16#D4, Unpack, T, Data, Rest, Orig);
132132

133133
%% fixext 2 stores an integer and a byte array whose length is 2 bytes
134-
unpack_stream(<<16#D5, T:8, Data:2/binary, Rest/binary>>,
134+
unpack_stream(<<16#D5, T:1/signed-integer-unit:8, Data:2/binary, Rest/binary>>,
135135
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
136136
maybe_unpack_ext(16#D5, Unpack, T, Data, Rest, Orig);
137137

138138
%% fixext 4 stores an integer and a byte array whose length is 4 bytes
139-
unpack_stream(<<16#D6, T:8, Data:4/binary, Rest/binary>>,
139+
unpack_stream(<<16#D6, T:1/signed-integer-unit:8, Data:4/binary, Rest/binary>>,
140140
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
141141
maybe_unpack_ext(16#D6, Unpack, T, Data, Rest, Orig);
142142

143143
%% fixext 8 stores an integer and a byte array whose length is 8 bytes
144-
unpack_stream(<<16#D7, T:8, Data:8/binary, Rest/binary>>,
144+
unpack_stream(<<16#D7, T:1/signed-integer-unit:8, Data:8/binary, Rest/binary>>,
145145
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
146146
maybe_unpack_ext(16#D7, Unpack, T, Data, Rest, Orig);
147147

148148
%% fixext 16 stores an integer and a byte array whose length is 16 bytes
149-
unpack_stream(<<16#D8, T:8, Data:16/binary, Rest/binary>>,
149+
unpack_stream(<<16#D8, T:1/signed-integer-unit:8, Data:16/binary, Rest/binary>>,
150150
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
151151
maybe_unpack_ext(16#D8, Unpack, T, Data, Rest, Orig);
152152

153153
%% ext 8 stores an integer and a byte array whose length is upto (2^8)-1 bytes:
154-
unpack_stream(<<16#C7, Len:8, Type:8, Data:Len/binary, Rest/binary>>,
154+
unpack_stream(<<16#C7, Len:8, Type:1/signed-integer-unit:8, Data:Len/binary, Rest/binary>>,
155155
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
156156
maybe_unpack_ext(16#C7, Unpack, Type, Data, Rest, Orig);
157157

158158
%% ext 16 stores an integer and a byte array whose length is upto (2^16)-1 bytes:
159-
unpack_stream(<<16#C8, Len:16, Type:8, Data:Len/binary, Rest/binary>>,
159+
unpack_stream(<<16#C8, Len:16, Type:1/signed-integer-unit:8, Data:Len/binary, Rest/binary>>,
160160
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
161161
maybe_unpack_ext(16#C8, Unpack, Type, Data, Rest, Orig);
162162

163163
%% ext 32 stores an integer and a byte array whose length is upto (2^32)-1 bytes:
164-
unpack_stream(<<16#C9, Len:32, Type:8, Data:Len/binary, Rest/binary>>,
164+
unpack_stream(<<16#C9, Len:32, Type:1/signed-integer-unit:8, Data:Len/binary, Rest/binary>>,
165165
?OPTION{ext_unpacker=Unpack, original_list=Orig} = _Opt) ->
166166
maybe_unpack_ext(16#C9, Unpack, Type, Data, Rest, Orig);
167167

test/msgpack_ext_example_tests.erl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,33 @@ behaviour_test() ->
7070
Opt = [{ext, ?MODULE}],
7171
Term = {native, {self(), make_ref(), foobar, fun() -> ok end}},
7272
{ok, Term} = msgpack:unpack(msgpack:pack(Term, Opt), Opt).
73+
74+
75+
ext_typecode_range_test() ->
76+
%% typecode range from msgpack spec. [-128,-1] is the "reserved"
77+
%% range, [0,127] is the "user-defined" range.
78+
TypecodeMin = -128,
79+
TypecodeMax = 127,
80+
Packer = fun ({thing, N}, _) ->
81+
{ok, {N, msgpack:pack(N)}}
82+
end,
83+
Unpacker = fun(N, Bin, _) ->
84+
Result = msgpack:unpack(Bin),
85+
?assertEqual({ok, N}, Result),
86+
Result
87+
end,
88+
Opt = [{ext,{Packer,Unpacker}}],
89+
%% it should be possible to use an uncontroversial ext type code:
90+
Enc = msgpack:pack({thing,1}, Opt),
91+
?assertMatch({ok, 1}, msgpack:unpack(Enc, Opt)),
92+
%% it should be possible to use ext typecodes covering the entire
93+
%% range specified in the msgpack specification:
94+
[begin
95+
Encoded = msgpack:pack({thing, N}, Opt),
96+
Result = msgpack:unpack(Encoded, Opt),
97+
?assertMatch({ok, N}, Result)
98+
end || N <- lists:seq(TypecodeMin,TypecodeMax)],
99+
%% using codes outside the allowed range should fail:
100+
[?assertError({case_clause, _}, msgpack:pack({thing, N}, Opt))
101+
|| N <- [-129, 128]],
102+
ok.

0 commit comments

Comments
 (0)