Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
886 stars 241 forks source link

Problem with deserialization of structure - Assertion newOffset <= _endReadOffset #249

Closed hanusek closed 2 years ago

hanusek commented 2 years ago

What's your question?

How to fix it?

Additional Context

Hello. I have a problem with the deserialization of my structure. (Assertion newOffset <= _endReadOffset)

I have two strings (wrapped by Text4b) in the struct:

struct AuthFrameResponse
{
    MessageType msg_type;
    Text4b refresh_token;
    Text4b access_token;
}
struct Text4b
{
   uint32_t content_size{0};
   std::string content;
   static constexpr uint32_t MaxSize = std::numeric_limits<uint32_t>::max();

   template <typename S>
   void serialize(S &s)
   {
          if(content.size() > MaxSize)
          {
            throw std::runtime_error("content is too long");
          }

          s.value4b(content_size);          
          content.resize(content_size);

          for(uint i=0; i<content_size; i++)
          {
              char c; 
              s.value1b(c);
              content.push_back(c);
          }
    }
};

Code:

struct BitseryConfig
{
    static constexpr bitsery::EndiannessType Endianness = bitsery::DefaultConfig::Endianness;
    static constexpr bool CheckAdapterErrors            = false;
    static constexpr bool CheckDataErrors               = false;

}; // struct BitseryConfig

template <class T>
bool fromBitseryBinary(std::vector<uint8_t> &bytes, T &t)
{
    using InputAdapter = bitsery::InputBufferAdapter<std::vector<uint8_t>, BitseryConfig>;

    auto state = bitsery::quickDeserialization<InputAdapter, T>(InputAdapter(std::begin(bytes), bytes.size()), t);
    return state.first == bitsery::ReaderError::NoError;
}

namespace AuthProtocol 
{
    enum class MessageType : uint32_t 
    { 
      RES  = 0,
      AUTH_INIT,
      AUTH_ERROR,
      UPDATE_ACCESS_TOKEN_REQUEST,
      UPDATE_ACCESS_TOKEN_RESPONSE,
      CMD
    };

    struct Text4b
    {
      uint32_t content_size{0};
      std::string content;
      static constexpr uint32_t MaxSize = std::numeric_limits<uint32_t>::max();

      template <typename S>
      void serialize(S &s)
      {
          if(content.size() > MaxSize)
          {
            throw std::runtime_error("content is too long");
          }

          s.value4b(content_size);          
          content.resize(content_size);

          for(uint i=0; i<content_size; i++)
          {
              char c; 
              s.value1b(c);
              content.push_back(c);
          }
      }
    };

    struct AuthFrameResponse
    {
        MessageType t;
        Text4b refresh_token;
        Text4b access_token;

        template <typename S>
        void serialize(S &s)
        {
            s.value4b(t);
            s.object(refresh_token);
            s.object(access_token);
        }
    };
}// namespace

///... read via tcp

   boost::asio::async_read(_socket, boost::asio::buffer(_recv_data), boost::asio::transfer_at_least(512), [&] (boost::system::error_code error, std::size_t bytes_transferred)
    {            
        if (error)
        {        
            std::cout << "RECV ERR message: " << error.message() << std::endl;
        }
        else if(bytes_transferred != 0)
        {   
            std::cout << "receive_auth_response bytes_transferred: " << bytes_transferred << std::endl;
                AuthProtocol::AuthFrameResponse response;
                if (!fromBitseryBinary(_recv_data, response))
                {
                    std::cout << "fromBitseryBinary error"  << std::endl;
                    return;
                }
          }
    });

Error:

receive_auth_response bytes_transferred: 722
/home/mhanusek/.conan/data/bitsery/5.1.0/_/_/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/bitsery/adapter/buffer.h:120: void bitsery::InputBufferAdapter<Buffer, Config>::readInternalValueChecked(bitsery::InputBufferAdapter<Buffer, Config>::TValue*, std::false_type) [with long unsigned int SIZE = 1; Buffer = std::vector<unsigned char>; Config = BitseryConfig; bitsery::InputBufferAdapter<Buffer, Config>::TValue = unsigned char; std::false_type = std::integral_constant<bool, false>]: Assertion `newOffset <= _endReadOffset' failed.
Thalhammer commented 2 years ago

@hanusek I am like 99.9% sure you posted this on the wrong github repo.

hanusek commented 2 years ago

@hanusek I am like 99.9% sure you posted this on the wrong github repo.

Yes ;) Please remove this issue.