Skip to content

Commit 669d954

Browse files
committed
When partially deserializing properly packed and unpacked repeated fields.
Skip packed fields if the number of bytes is zero. At least allocated an element for unpacked fields when the number of bytes for that one unpacked field is zero.
1 parent ad3ff2a commit 669d954

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

src/RepeatedField.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,8 @@ namespace EmbeddedProto
346346
return_value = WireFormatter::DeserializeVarint(buffer, n_bytes_to_include_in_section);
347347
}
348348

349-
if(Error::NO_ERRORS == return_value)
349+
// If there are no bytes in the array do not start deserializing data.
350+
if((Error::NO_ERRORS == return_value) && (0 < n_bytes_to_include_in_section))
350351
{
351352
ReadBufferSection bufferSection(buffer, n_bytes_to_include_in_section);
352353
DATA_TYPE x;
@@ -404,20 +405,26 @@ namespace EmbeddedProto
404405

405406
if(Error::NO_ERRORS == return_value)
406407
{
407-
ReadBufferSection bufferSection(buffer, n_bytes_to_include_in_section);
408+
// Even if the number of bytes is zero we should allocate the element in the array.
409+
auto& element = this->get(index);
408410

409-
// See how many bytes we will now process from the buffer and thus how many bytes are left for the next iteration.
410-
n_bytes_to_include_in_section -= bufferSection.get_size();
411+
if(0 < n_bytes_to_include_in_section)
412+
{
413+
ReadBufferSection bufferSection(buffer, n_bytes_to_include_in_section);
411414

412-
return_value = this->get(index).deserialize(bufferSection);
415+
// See how many bytes we will now process from the buffer and thus how many bytes are left for the next iteration.
416+
n_bytes_to_include_in_section -= bufferSection.get_size();
413417

414-
n_bytes_to_include_in_section += bufferSection.get_size();
418+
return_value = element.deserialize(bufferSection);
415419

416-
// In case we have bytes we still need to receive set the end of buffer return value.
417-
// The return value of deserialize has priority.
418-
if((::EmbeddedProto::Error::NO_ERRORS == return_value) && (0 < n_bytes_to_include_in_section))
419-
{
420-
return_value = ::EmbeddedProto::Error::END_OF_BUFFER;
420+
n_bytes_to_include_in_section += bufferSection.get_size();
421+
422+
// In case we have bytes we still need to receive set the end of buffer return value.
423+
// The return value of deserialize has priority.
424+
if((::EmbeddedProto::Error::NO_ERRORS == return_value) && (0 < n_bytes_to_include_in_section))
425+
{
426+
return_value = ::EmbeddedProto::Error::END_OF_BUFFER;
427+
}
421428
}
422429
}
423430
}

test/test_RepeatedFieldMessage.cpp

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -359,23 +359,28 @@ TEST(RepeatedFieldMessage, serialize_fault_buffer_full)
359359

360360
TEST(RepeatedFieldMessage, deserialize_empty_array)
361361
{
362+
InSequence s;
362363
repeated_fields<Y_SIZE> msg;
363364

364365
Mocks::ReadBufferMock buffer;
365-
EXPECT_CALL(buffer, pop(_)).WillRepeatedly(Return(false));
366-
EXPECT_CALL(buffer, get_size()).WillRepeatedly(Return(0));
366+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<1>(0x12), Return(true))); // Tag of y
367+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<1>(0x00), Return(true)));// Size of y = 0
368+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(Return(false));
367369

368370
EXPECT_EQ(::EmbeddedProto::Error::NO_ERRORS, msg.deserialize(buffer));
369371

370372
}
371373

372374
TEST(RepeatedFieldMessage, deserialize_empty_message_array)
373375
{
376+
InSequence s;
377+
374378
repeated_message<Y_SIZE> msg;
375379

376380
Mocks::ReadBufferMock buffer;
377-
EXPECT_CALL(buffer, pop(_)).WillRepeatedly(Return(false));
378-
EXPECT_CALL(buffer, get_size()).WillRepeatedly(Return(0));
381+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<1>(0x12), Return(true)));// Tag of b
382+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<1>(0x00), Return(true)));// Size of b = 0
383+
EXPECT_CALL(buffer, peek(_, _)).Times(1).WillOnce(Return(false));
379384

380385
EXPECT_EQ(::EmbeddedProto::Error::NO_ERRORS, msg.deserialize(buffer));
381386
}
@@ -420,11 +425,13 @@ TEST(RepeatedFieldMessage, deserialize_one_partial)
420425

421426
EmbeddedProto::ReadBufferFixedSize<SIZE> buffer({
422427
0x08, 0x01, // x tag and value
423-
0x12, 0x03}); // y tag and size.
424-
428+
0x12}); // y tag
429+
430+
buffer.push(0x03); //y size
425431

426432
EXPECT_EQ(::EmbeddedProto::Error::END_OF_BUFFER, msg.deserialize(buffer));
427-
433+
434+
428435
buffer.push(0x01); // start of y data.
429436
buffer.push(0x01);
430437
buffer.push(0x01);
@@ -455,7 +462,7 @@ TEST(RepeatedFieldMessage, deserialize_one_message_array)
455462
ON_CALL(buffer, get_size()).WillByDefault(Return(SIZE));
456463

457464
std::array<uint8_t, SIZE> referee = { 0x08, 0x01, // x
458-
0x12, 0x00, 0x12, 0x04, 0x08, 0x01, 0x10, 0x01, 0x12, 0x00, // y
465+
0x12, 0x00, 0x12, 0x04, 0x08, 0x01, 0x10, 0x01, 0x12, 0x00, // b
459466
0x18, 0x01}; // z
460467

461468
for(auto r: referee)
@@ -491,11 +498,11 @@ TEST(RepeatedFieldMessage, deserialize_mixed_message_array)
491498

492499
ON_CALL(buffer, get_size()).WillByDefault(Return(SIZE));
493500

494-
std::array<uint8_t, SIZE> referee = { 0x12, 0x00, // y[0]
501+
std::array<uint8_t, SIZE> referee = { 0x12, 0x00, // b[0]
495502
0x08, 0x01, // x
496-
0x12, 0x04, 0x08, 0x01, 0x10, 0x01, // y[1]
503+
0x12, 0x04, 0x08, 0x01, 0x10, 0x01, // b[1]
497504
0x18, 0x01, // z
498-
0x12, 0x00, }; // y[2]
505+
0x12, 0x00, }; // b[2]
499506

500507
for(auto r: referee)
501508
{

0 commit comments

Comments
 (0)