Skip to content

Commit

Permalink
IGNITE-23598 Fix LengthPrefixCodec issue with 3 byte buffer (#11777)
Browse files Browse the repository at this point in the history
  • Loading branch information
isapego authored Jan 9, 2025
1 parent 483ea0e commit f4ff01c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ namespace ignite
*
* @param data Data.
* @param pos Start of data.
* @param len Length.
* @param end End of the data.
*/
DataBuffer(const impl::interop::SP_ConstInteropMemory& data, int32_t pos, int32_t len);
DataBuffer(const impl::interop::SP_ConstInteropMemory& data, int32_t pos, int32_t end);

/**
* Destructor.
Expand Down Expand Up @@ -127,8 +127,8 @@ namespace ignite
/** Position in current data. */
int32_t position;

/** Data length. */
int32_t length;
/** End position. */
int32_t endPos;

/** Data */
impl::interop::SP_ConstInteropMemory data;
Expand Down
20 changes: 10 additions & 10 deletions modules/platforms/cpp/network/src/network/data_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ namespace ignite
{
DataBuffer::DataBuffer() :
position(0),
length(0),
endPos(0),
data()
{
// No-op.
}

DataBuffer::DataBuffer(const impl::interop::SP_ConstInteropMemory& data0) :
position(0),
length(data0.Get()->Length()),
endPos(data0.Get()->Length()),
data(data0)
{
// No-op.
}

DataBuffer::DataBuffer(const impl::interop::SP_ConstInteropMemory& data0, int32_t pos, int32_t len) :
DataBuffer::DataBuffer(const impl::interop::SP_ConstInteropMemory& data0, int32_t pos, int32_t end) :
position(pos),
length(len),
endPos(end),
data(data0)
{
// No-op.
Expand Down Expand Up @@ -75,7 +75,7 @@ namespace ignite
if (!data.IsValid())
return 0;

return length - position;
return endPos - position;
}

bool DataBuffer::IsEmpty() const
Expand All @@ -98,7 +98,7 @@ namespace ignite

impl::interop::InteropInputStream DataBuffer::GetInputStream() const
{
impl::interop::InteropInputStream stream = impl::interop::InteropInputStream(data.Get(), length);
impl::interop::InteropInputStream stream = impl::interop::InteropInputStream(data.Get(), endPos);
stream.Position(position);

return stream;
Expand All @@ -109,11 +109,11 @@ namespace ignite
if (IsEmpty())
return DataBuffer();

impl::interop::SP_InteropMemory mem(new impl::interop::InteropUnpooledMemory(length));
mem.Get()->Length(length);
std::memcpy(mem.Get()->Data(), data.Get()->Data() + position, length);
impl::interop::SP_InteropMemory mem(new impl::interop::InteropUnpooledMemory(endPos));
mem.Get()->Length(endPos);
std::memcpy(mem.Get()->Data(), data.Get()->Data() + position, endPos);

return DataBuffer(mem, 0, length);
return DataBuffer(mem, 0, endPos);
}

void DataBuffer::Skip(int32_t bytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace ignite

DataBuffer LengthPrefixCodec::Decode(DataBuffer& data)
{
if (packet.IsValid() && packet.Get()->Length() == (PACKET_HEADER_SIZE + packetSize))
if (packet.IsValid() && packetSize != -1 && packet.Get()->Length() == (PACKET_HEADER_SIZE + packetSize))
{
packetSize = -1;
packet.Get()->Length(0);
Expand Down
1 change: 1 addition & 0 deletions modules/platforms/cpp/thin-client-test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ set(SOURCES
src/test_utils.cpp
src/ignite_client_test.cpp
src/interop_test.cpp
src/network_codec_test.cpp
src/scan_query_test.cpp
src/sql_fields_query_test.cpp
src/auth_test.cpp
Expand Down
49 changes: 49 additions & 0 deletions modules/platforms/cpp/thin-client-test/src/network_codec_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <boost/test/unit_test.hpp>

#include <ignite/impl/interop/interop.h>
#include <ignite/network/length_prefix_codec.h>

using namespace boost::unit_test;
using namespace ignite::network;


BOOST_AUTO_TEST_SUITE(NetworkCodecTestSuite)

BOOST_AUTO_TEST_CASE(LengthPrefixCodec_3bytes)
{
ignite::impl::interop::SP_InteropMemory mem(new ignite::impl::interop::InteropUnpooledMemory(8));
ignite::impl::interop::InteropOutputStream stream(mem.Get());
stream.WriteInt32(4);
stream.WriteInt32(123456789);

DataBuffer in1(mem, 0, 3);
DataBuffer in2(mem, 3, 8);

SP_Codec codec(new LengthPrefixCodec());

DataBuffer out1 = codec.Get()->Decode(in1);
BOOST_CHECK(out1.IsEmpty());

DataBuffer out2 = codec.Get()->Decode(in2);
BOOST_CHECK(!out2.IsEmpty());
BOOST_CHECK_EQUAL(out2.GetSize(), 8);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit f4ff01c

Please sign in to comment.