Consider the code below for a second:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
write(pipefd[1], buffer, bytes);
close(pipefd[1]);
wait(NULL);
Here I read fd, write data to the pipe and close the pipe. This allows to eventually upload tiny images that can be rendered. However, if I do everything the same, only replace char array with std::istringstream, as in the example below:
char buffer[4000];
size_t bytes = recv(fd, buffer, 4000, 0);
std::istringstream data(buffer);
write(pipefd[1], data.str().c_str(), bytes);
close(pipefd[1]);
wait(NULL);
Then image is uploaded but cannot be rendered. (Via pipes this C program communicates with a php-cgi script).
Also:
if (strcmp(data.str().c_str(), buffer) == 0)
// returns true
I am very curious as to why this could be the case.
CodePudding user response:
If you run on Windows, then C streams add carriage return \r
after single \n
automatically while reading and writing. The fix is simple
std::istringstream data(buffer, std::ios::binary);
MacOS is configurable for using any of \r
, \n
, \r\n
. You should never expect what is used and always apply the stream mode std::ios::binary
for binary data.
However the both code snippets are not valid, std::istringstream data(buffer)
and std::string data(buffer)
use bytes in data
until first zero byte met.
CodePudding user response:
std::istringstream data(buffer);
This assumes buffer
is a null-terminated string. Binary data typically contains 0x00
bytes, thus you would end up truncating the buffer
contents.
Use this instead:
std::istringstream data(std::string(buffer, bytes), std::ios::binary);