msgpack / msgpack-c

MessagePack implementation for C and C++ / msgpack.org[C/C++]
Other
3.03k stars 883 forks source link

Result is null when pack string data (data length = 256 or 512 or 1024 or 2048, or comform to 2^n and > 128) #1056

Closed opandad closed 1 year ago

opandad commented 1 year ago

Describe the bug It will output null data after pack data which length 256, 512, 1024, 2048.

msgpack-cxx 3.3.0 and msgpack-cxx 6.0.0

To Reproduce

// unnormal length=1024
std::string testStr = "1234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678";  // length = 1024

std::stringstream ss;

msgpack::pack(ss, testStr);

std::cout << ss.str().c_str() << std::endl;
// normal length=1023
std::string testStr = "123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567";  // length = 1023

std::stringstream ss;

msgpack::pack(ss, testStr);

std::cout << ss.str().c_str() << std::endl;
std::string testStr = "";
for(int i = 0; i < 50000; i++){
    char a[70001] = {};
    testStr += 'a';
    std::stringstream ss;
    msgpack::pack(ss, testStr);
    std::string temp = ss.str();
    strcat(a, temp.c_str());
    if(strlen(a) <= 5){
        std::cout << i+1 << std::endl;
    }
}

I test in local, find out pack.hpp when l != 2^n, buf[2] will = 'd'; when l = 2^n, buf[2] will = 2

And I hardcode buf[2] = 'd', c_str() is normal.

image

Expected behavior Can output the data when after pack data

redboltz commented 1 year ago

I need https://stackoverflow.com/help/minimal-reproducible-example

opandad commented 1 year ago

Write for the first time, sorry!

opandad commented 1 year ago

Run it in ubuntu20.04, Intel cpu

#include <iostream>
#include <sstream>
#include <msgpack.hpp>

int main(){
    std::string testStr = "";
    for(int i = 0; i < 70000; i++){
        char a[70001] = {};
        testStr += 'a';
        std::stringstream ss;
        msgpack::pack(ss, testStr);
        std::string temp = ss.str();
        strcat(a, temp.c_str());
        if(strlen(a) <= 2){
            std::cout << i+1 << std::endl;
        }
    }
    return 0;
}
redboltz commented 1 year ago

The packed data is MessagePack formatted byte data. It is different from the original (before packed) data. See https://github.com/msgpack/msgpack/blob/master/spec.md#str-format-family

It would contain any binary byte 0x00..0xff. So strlen() doesn't work well.

opandad commented 1 year ago

How can I do let it work well, or how can I know the strlen().

opandad commented 1 year ago

I want to split it when after pack the str data.How can I do?

redboltz commented 1 year ago

I don't know why you cancat packed data. Simply don't concat, then you can get splitted packed data.

Or unpack with offset https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker

redboltz commented 1 year ago

Maybe you need to laern a lot of things before using msgpack-c. For example, non-null terminated string behavior. strcat is also unreliable in this case.

opandad commented 1 year ago

I get it, thank you!