Skip to content

Commit 0a8d92c

Browse files
Jens-Gclaude
andcommitted
THRIFT-6030: Harden Erlang binary protocol negative sizes
Client: erl Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3a4ea35 commit 0a8d92c

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

‎lib/erl/src/thrift_binary_protocol.erl‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ read(This0, map_begin) ->
220220
{This1, {ok, Ktype}} = read(This0, byte),
221221
{This2, {ok, Vtype}} = read(This1, byte),
222222
{This3, {ok, Size}} = read(This2, i32),
223+
if Size < 0 -> error({protocol_error, negative_size}); true -> ok end,
223224
{This3, #protocol_map_begin{
224225
ktype = Ktype,
225226
vtype = Vtype,
@@ -230,6 +231,7 @@ read(This, map_end) ->
230231
read(This0, list_begin) ->
231232
{This1, {ok, Etype}} = read(This0, byte),
232233
{This2, {ok, Size}} = read(This1, i32),
234+
if Size < 0 -> error({protocol_error, negative_size}); true -> ok end,
233235
{This2, #protocol_list_begin{
234236
etype = Etype,
235237
size = Size
@@ -239,6 +241,7 @@ read(This, list_end) ->
239241
read(This0, set_begin) ->
240242
{This1, {ok, Etype}} = read(This0, byte),
241243
{This2, {ok, Size}} = read(This1, i32),
244+
if Size < 0 -> error({protocol_error, negative_size}); true -> ok end,
242245
{This2, #protocol_set_begin{
243246
etype = Etype,
244247
size = Size
@@ -298,6 +301,7 @@ read(This0, double) ->
298301
% returns a binary directly, call binary_to_list if necessary
299302
read(This0, string) ->
300303
{This1, {ok, Sz}} = read(This0, i32),
304+
if Sz < 0 -> error({protocol_error, negative_size}); true -> ok end,
301305
read_data(This1, Sz).
302306

303307
-spec read_data(#binary_protocol{}, non_neg_integer()) ->
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
%%
2+
%% Licensed to the Apache Software Foundation (ASF) under one
3+
%% or more contributor license agreements. See the NOTICE file
4+
%% distributed with this work for additional information
5+
%% regarding copyright ownership. The ASF licenses this file
6+
%% to you under the Apache License, Version 2.0 (the
7+
%% "License"); you may not use this file except in compliance
8+
%% with the License. You may obtain a copy of the License at
9+
%%
10+
%% http://www.apache.org/licenses/LICENSE-2.0
11+
%%
12+
%% Unless required by applicable law or agreed to in writing,
13+
%% software distributed under the License is distributed on an
14+
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
%% KIND, either express or implied. See the License for the
16+
%% specific language governing permissions and limitations
17+
%% under the License.
18+
%%
19+
20+
-module(test_thrift_binary_protocol).
21+
-include_lib("eunit/include/eunit.hrl").
22+
-include("thrift_protocol.hrl").
23+
24+
new(Buf) ->
25+
{ok, Transport} = thrift_membuffer_transport:new(Buf),
26+
{ok, Protocol} = thrift_binary_protocol:new(Transport),
27+
Protocol.
28+
29+
read(This, Type) -> thrift_protocol:read(This, Type).
30+
31+
negative_map_size_test() ->
32+
%% ktype=8 (I32), vtype=11 (STRING), size=-1 (0xffffffff big-endian)
33+
P = new(<<8, 11, 255, 255, 255, 255>>),
34+
?assertError({protocol_error, negative_size}, read(P, map_begin)).
35+
36+
negative_list_size_test() ->
37+
%% etype=11 (STRING), size=-1
38+
P = new(<<11, 255, 255, 255, 255>>),
39+
?assertError({protocol_error, negative_size}, read(P, list_begin)).
40+
41+
negative_set_size_test() ->
42+
%% etype=11 (STRING), size=-1
43+
P = new(<<11, 255, 255, 255, 255>>),
44+
?assertError({protocol_error, negative_size}, read(P, set_begin)).
45+
46+
negative_string_size_test() ->
47+
%% size=-1
48+
P = new(<<255, 255, 255, 255>>),
49+
?assertError({protocol_error, negative_size}, read(P, string)).

0 commit comments

Comments
 (0)