See bottom for TL;DR
Background info: (for perspective)
I am implementing a client-server, the client requests data, sending via a set char buffer, with set size of char[256]
The server responds in kind with a 2 stage response, first sending a 'header packet' using a header buffer (on both client and server with size char[20]), containing the number of packets to follow and the size of the largest packet to be sent (to allocate the "data" buffer),
assume the text sent from server is as follows
QString text = QString("TOKEN=1SOMETOKENSTRING123;");
//length of text = 26 char
this "header packet" is successfully received, parsed and implemented with no defects in converting to a QString by using:
//header
char header_buffer[20];
bzero(header_buffer, sizeof (header_buffer));
//assign header_buffer using socket.recv()
QString header = QString(header_buffer);
This is done successfully
Problem info:
The header is parsed and outputs attributes size (The max packet size) and count(number of 'data' packets to follow)
Here lies the problem area:
//data packet section
//returns the size of largest packet using the received "header packet" - done successfully
int maxSize = getMaxPacketSize(header_buffer);
//maxSize = 27 char, which is the length of the 'text' String sent from the server, thus
char data_buffer[maxSize]; //char[27]
bzero(data_buffer, sizeof (data_buffer));
//assign data_buffer using socket.recv()
QString data = QString(data_buffer);
qDebug() << data_buffer;   CORRECT  //displays "TOKEN=1SOMETOKENSTRING123;"
qDebug() << data;          ERROR    //displays "TOKEN=1SOMETOKENSTRING123;UUU" 
Exact Problem:
Creating new QString from a char[] adds 3 'U' characters to the end of string:
Basic example:
char cArray[27] //assume it has contents to fill all, size/count = 27
QString str = QString(cArray);
int len = str.length();
//len = 30, last 3 char of str = "UUU"
Data Example(**actually data):
    int packetSize = getMaxPacketSize(buffer); buffer[20] = "COUNT=2;SIZE=27;\000\000\000\000"
    char packet[packetSize]; // = 27
    size_t size = sizeof (packet); // = 27 
    bzero(packet, sizeof (packet));
    if (recv(sockfd,packet,sizeof (packet),0) < 0) {
        qDebug() << "ERROR netman: reading data from socket";
        //more code here
    }
    //Add packet to packet_data list
    //NOTE : QList<QString> packet_data = QList<QString>();
    //NOTE: packet[27] = "TOKEN=a7nCrDbaycWx2JzMir4m;"
    packet_data.insert(packetSize-packetNum,QString(packet)); 
    QString d = packet_data.first(); d = "TOKEN=a7nCrDbaycWx2JzMir4m;UUU"
Debugger Data for verbosity's sake
Locals      
    d   "TOKEN=a7nCrDbaycWx2JzMir4m;UUU"    QString
        [0] 'T'     84  0x0054  QChar
        [1] 'O'     79  0x004f  QChar
        [2] 'K'     75  0x004b  QChar
        [3] 'E'     69  0x0045  QChar
        [4] 'N'     78  0x004e  QChar
        [5] '='     61  0x003d  QChar
        [6] 'a'     97  0x0061  QChar
        [7] '7'     55  0x0037  QChar
        [8] 'n'     110 0x006e  QChar
        [9] 'C'     67  0x0043  QChar
        [10]    'r'     114 0x0072  QChar
        [11]    'D'     68  0x0044  QChar
        [12]    'b'     98  0x0062  QChar
        [13]    'a'     97  0x0061  QChar
        [14]    'y'     121 0x0079  QChar
        [15]    'c'     99  0x0063  QChar
        [16]    'W'     87  0x0057  QChar
        [17]    'x'     120 0x0078  QChar
        [18]    '2'     50  0x0032  QChar
        [19]    'J'     74  0x004a  QChar
        [20]    'z'     122 0x007a  QChar
        [21]    'M'     77  0x004d  QChar
        [22]    'i'     105 0x0069  QChar
        [23]    'r'     114 0x0072  QChar
        [24]    '4'     52  0x0034  QChar
        [25]    'm'     109 0x006d  QChar
        [26]    ';'     59  0x003b  QChar
        [27]    'U'     85  0x0055  QChar
        [28]    'U'     85  0x0055  QChar
        [29]    'U'     85  0x0055  QChar
    message "AUTH;U=user@example;P=Pass;"   char *
    packet  "TOKEN=a7nCrDbaycWx2JzMir4m;"   char [27]
    packetNum   1   int
    packetSize  27  int
    s   "COUNT=2;SIZE=27;"  QString
    size    27  size_t
    this    @0x7fffffffd190 netman
        buffer  "COUNT=2;SIZE=27;\000\000\000\000"  char [20]
        cli_addr    @0x7fffffffd1c0 sockaddr_in
        clilen  1431695692  socklen_t
        n   1436538608  int
        newsockfd   32767   int
        packet_data <1 items>   QList<QString>
        serv_addr   @0x7fffffffd1b0 sockaddr_in
        server  @0x7ffff5f071c0 hostent
        sockfd  13  int
I have no idea where these 3 extra char's come from!
Anyone any suggestions/ideas?
The major problem here is that you're passing a char* to functions that expect a c-string. That is, a string with a zero value at the end. But your input from the socket doesn't contain such a byte.
Reading past the end of an array is undefined behavior, but in this case it's fairly easy to reason what happens: bytes are read until a null value isn't found, and it's found fairly soon (after 3 more bytes)1.
You can easily fix it by using functions that take exact number of bytes they're supposed to read from an array.
The simplest way is to use fromUtf8 or fromLatin1 or fromLocal8Bit member function of QString to provide the number of bytes you want to read:
QString str = QString::fromUtf8(cArray, number_of_bytes);
That being said, consider using QByteArray for data read from the network:
QByteArray data(cArray, number_of_bytes);
1 reasoning what happens with undefined behavior should be taken with grain of salt, because compilers are free to do almost anything if they can probe it happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With