Project

General

Profile

Actions

Bug #2728

closed

Block::fromStream decode error when TLV-LENGTH equals whitespace

Added by Junxiao Shi almost 9 years ago. Updated almost 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Base
Target version:
Start date:
04/04/2015
Due date:
% Done:

100%

Estimated time:
3.00 h

Description

Snippet to reproduce:

// g++ -std=c++0x x.cpp $(pkg-config --cflags --libs libndn-cxx)
#include <ndn-cxx/data.hpp>

using namespace ndn;

int
main()
{
  uint8_t PACKET[] = {
  0x06, 0x20, // Data
        0x07, 0x11, // Name
              0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, // NameComponent 'hello'
              0x08, 0x01, 0x31, // NameComponent '1'
              0x08, 0x05, 0x77, 0x6f, 0x72, 0x6c, 0x64, // NameComponent 'world'
        0x14, 0x00, // MetaInfo empty
        0x15, 0x00, // Content empty
        0x16, 0x05, // SignatureInfo
               0x1b, 0x01, 0x01, // SignatureType RSA
               0x1c, 0x00, // KeyLocator empty
        0x17, 0x00 // SignatureValue empty
  };

  std::stringstream stream;
  stream.write(reinterpret_cast<const char*>(PACKET), sizeof(PACKET));
  stream.seekg(0);

  Block block = Block::fromStream(stream);
  block.parse();

  return 0;
}

Expected: no error

Actual:

terminate called after throwing an instance of 'ndn::tlv::Error'
  what():  TLV length exceeds buffer length

Debug:

(gdb) bt
#0  0x00007ffff711a0d5 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff711d83b in __GI_abort () at abort.c:91
#2  0x00007ffff777069d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff776e846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff776e873 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff776e96e in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x0000000000406f89 in ndn::Block::parse (this=0x7fffffffe410) at ../src/encoding/block.cpp:313
#7  0x0000000000404ae8 in main ()
(gdb) up 6
#6  0x0000000000406f89 in ndn::Block::parse (this=0x7fffffffe410) at ../src/encoding/block.cpp:313
313           throw tlv::Error("TLV length exceeds buffer length");
(gdb) p type
$1 = 17
(gdb) p length
$2 = 8
(gdb) p *this
$3 = {m_buffer = {<std::__shared_ptr<ndn::Buffer const, (__gnu_cxx::_Lock_policy)2>> = {_M_ptr = 0x621240, _M_refcount = {
        _M_pi = 0x621280}}, <No data fields>}, m_type = 6, m_begin = {_M_current = 0x621260 "\006\a\021\b\005hell"}, m_end = {
    _M_current = 0x621269 ""}, m_size = 9, m_value_begin = {_M_current = 0x621262 "\021\b\005hell"}, m_value_end = {
    _M_current = 0x621269 ""}, m_subBlocks = {<std::_Vector_base<ndn::Block, std::allocator<ndn::Block> >> = {
      _M_impl = {<std::allocator<ndn::Block>> = {<__gnu_cxx::new_allocator<ndn::Block>> = {<No data fields>}, <No data fields>}, 
        _M_start = 0x0, _M_finish = 0x0, _M_end_of_storage = 0x0}}, <No data fields>}}
(gdb) x/34x m_begin._M_current
0x621260:   0x06    0x07    0x11    0x08    0x05    0x68    0x65    0x6c
0x621268:   0x6c    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x621270:   0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x621278:   0x21    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x621280:   0x30    0xfc

It seems that top-level element's TLV-LENGTH octet (0x20) is lost.


Related issues 2 (0 open2 closed)

Related to ndnSIM - Bug #2559: ndnSIM loses ALL data packets when payload size is set to a certain numberClosed02/25/2015

Actions
Has duplicate ndnSIM - Bug #2727: Convert::ToPacket<Data> off-by-oneClosed04/04/2015

Actions
Actions #1

Updated by Junxiao Shi almost 9 years ago

  • Has duplicate Bug #2727: Convert::ToPacket<Data> off-by-one added
Actions #2

Updated by Junxiao Shi almost 9 years ago

  • Subject changed from Block::fromStream lost TLV-LENGTH octet to Block::fromStream decode error when TLV-LENGTH equals whitespace
  • Estimated time changed from 1.00 h to 3.00 h

Further debug reveals that the std::istream_iterator<uint8_t> is skipping the 0x20 character.

(gdb) break ndn::Block::fromStream
Breakpoint 1 at 0x4062fe: file ../src/encoding/block.cpp, line 201.
(gdb) run
Starting program: /home/shijunxiao/snippet/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, ndn::Block::fromStream (is=...) at ../src/encoding/block.cpp:201
201 {
(gdb) n
202   std::istream_iterator<uint8_t> tmp_begin(is);
(gdb) 
203   std::istream_iterator<uint8_t> tmp_end;
(gdb) p *tmp_begin
$1 = (const unsigned char &) @0x7fffffffbfc8: 6 '\006'
(gdb) p ++tmp_begin
$2 = (
    std::istream_iterator<unsigned char, char, std::char_traits<char>, long> &) @0x7fffffffbfc0: {<std::iterator<std::input_iterator_tag, unsigned char, long, unsigned char const*, unsigned char const&>> = {<No data fields>}, _M_stream = 0x7fffffffe2a0, 
  _M_value = 7 '\a', _M_ok = true}
(gdb) p *tmp_begin
$3 = (const unsigned char &) @0x7fffffffbfc8: 7 '\a'
(gdb) p ++tmp_begin
$4 = (
    std::istream_iterator<unsigned char, char, std::char_traits<char>, long> &) @0x7fffffffbfc0: {<std::iterator<std::input_iterator_tag, unsigned char, long, unsigned char const*, unsigned char const&>> = {<No data fields>}, _M_stream = 0x7fffffffe2a0, 
  _M_value = 17 '\021', _M_ok = true}

Advancing std::istream_iterator calls >> operator on the underlying std::istream.

operator<<(std::istream, char&) is a FormattedInputFunction, which will skip leading whitespace.

Therefore, 0x20 is treated as "whitespace" and skipped.

Actions #3

Updated by Junxiao Shi almost 9 years ago

  • Status changed from New to In Progress
  • Assignee set to Junxiao Shi

Solution: std::noskipws

Actions #4

Updated by Junxiao Shi almost 9 years ago

  • Status changed from In Progress to Code review
  • % Done changed from 0 to 100
Actions #5

Updated by Alex Afanasyev almost 9 years ago

  • Related to Bug #2559: ndnSIM loses ALL data packets when payload size is set to a certain number added
Actions #6

Updated by Junxiao Shi almost 9 years ago

  • Status changed from Code review to Closed
Actions

Also available in: Atom PDF