[QByteArray] Problems since Harmony 21.1

Hi,

We have implemented a WebSocket server inside Harmony (through QTcpServer because you dont have implemented QWebSocket class in Harmony) in order to get a direct communication between our Production System with the software.

It is working perfectly from Harmony 16 to Harmony 21 but it began to do something strange from Harmony 21.1 where you update QT version to QT6.

One of the problems with QByteArray in 21.1 is it’s not getting the data from the constructor. It works fine in Harmony 22 but not in 21.1

Code to reproduce:

const GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
var s_ws_key = "B5LCruNpGnXwaty761UOaA==";

// Creating ByteArrays with data in constructor
var key_array = new QByteArray(s_ws_key);
var guid_array = new QByteArray(GUID);

// Creating ByteArray appending to an empty QByteArray
var key_array2 = new QByteArray();
for(var i=0; i<s_ws_key.length;i++)
   key_array2.append(s_ws_key[i]);

var guid_array2  = new QByteArray();
for(var i=0; i<GUID.length;i++)
   guid_array2.append(GUID[i]);

MessageLog.trace("---------------------------");
MessageLog.trace("Data: " + key_array + "  -  Length:  " +  key_array.length() );
MessageLog.trace("Data: " + guid_array + "  -  Length:  " + guid_array.length() );
MessageLog.trace("---------------------------");
MessageLog.trace("Data: " + key_array2 + "  -  Length:  " + key_array2.length() );
MessageLog.trace("Data: " + guid_array2 + "  -  Length:  " + guid_array2.length() );
MessageLog.trace("---------------------------");

Output in all Harmony versions except 21.1

T: 18:06:09.324 ---------------------------
T: 18:06:09.324 Data: B5LCruNpGnXwaty761UOaA==  -  Length:  24
T: 18:06:09.325 Data: 258EAFA5-E914-47DA-95CA-C5AB0DC85B11  -  Length:  36
T: 18:06:09.325 ---------------------------
T: 18:06:09.325 Data: B5LCruNpGnXwaty761UOaA==  -  Length:  24
T: 18:06:09.325 Data: 258EAFA5-E914-47DA-95CA-C5AB0DC85B11  -  Length:  36
T: 18:06:09.325 ---------------------------

Output from Harmony 21.1 (In Harmony 22 it works fine again)

T: 18:11:04.585 ---------------------------
T: 18:11:04.586 Data:   -  Length:  0
T: 18:11:04.587 Data:   -  Length:  0
T: 18:11:04.588 ---------------------------
T: 18:11:04.589 Data: B5LCruNpGnXwaty761UOaA==  -  Length:  24
T: 18:11:04.589 Data: 258EAFA5-E914-47DA-95CA-C5AB0DC85B11  -  Length:  36
T: 18:11:04.590 ---------------------------

The other problem, I think its about unsigned and signed chars in QByteArray in the new QT6.

Code to reproduce:

 function encodeWebSocket(bytesRaw) {
       var bytesFormatted = new Array();
       bytesFormatted[0] = 129; // 129; /// fin_rsv_opcode: 129=one fragment, text, 130=one fragment, binary, 136=close connection. (with mask)

       if (bytesRaw.length <= 125) {
           bytesFormatted[1] = bytesRaw.length;
       } else if (bytesRaw.length >= 126 && bytesRaw.length <= 65535) {
           bytesFormatted[1] = 126;
           bytesFormatted[2] = ( bytesRaw.length >> 8 ) & 255;
           bytesFormatted[3] = ( bytesRaw.length      ) & 255;
       } else {
           bytesFormatted[1] = 127;
           bytesFormatted[2] = ( bytesRaw.length >> 56 ) & 255;
           bytesFormatted[3] = ( bytesRaw.length >> 48 ) & 255;
           bytesFormatted[4] = ( bytesRaw.length >> 40 ) & 255;
           bytesFormatted[5] = ( bytesRaw.length >> 32 ) & 255;
           bytesFormatted[6] = ( bytesRaw.length >> 24 ) & 255;
           bytesFormatted[7] = ( bytesRaw.length >> 16 ) & 255;
           bytesFormatted[8] = ( bytesRaw.length >>  8 ) & 255;
           bytesFormatted[9] = ( bytesRaw.length       ) & 255;
       }
       
       for (var i = 0; i < bytesRaw.length; i++){
           bytesFormatted.push(bytesRaw.charCodeAt(i));
       }
       
       return bytesFormatted;
   };   


var ret = '"Toon Boom Harmony 20|startup|bpy|1"';

  // Encoding frame with ret data for websocket
// In Modern version of chrome it says: A server must not mask any frames that it sends to the client.
var frameencoded = encodeWebSocket(ret);
MessageLog.trace("Frame Encoded: " + frameencoded);
                        
// We need to add the data to a QByteArray (converting binary data to chars)
var data = new QByteArray();
for(var i=0; i<frameencoded.length; i++)
   data.append(String.fromCharCode(frameencoded[i]));
                        
MessageLog.trace("ByteArray Data: " + data);
MessageLog.trace("ByteArray Length: " + data.length());

In Harmony pre-21.1 with QT4, it works perfectly. This is the output:

T: 18:21:48.087 Msg to Send: "Toon Boom Harmony 20|startup|bpy|1"
T: 18:21:48.087 Frame Encoded: 129,36,34,84,111,111,110,32,66,111,111,109,32,72,97,114,109,111,110,121,32,50,48,124,115,116,97,114,116,117,112,124,98,112,121,124,49,34
T: 18:21:48.088 ByteArray Data: $"Toon Boom Harmony 20|startup|bpy|1"
T: 18:21:48.088 ByteArray Length: 38

This is the output from Harmony 21.1

T: 18:22:58.232 Msg to Send: "Toon Boom Harmony 20|startup|bpy|1"
T: 18:22:58.232 Frame Encoded: 129,36,34,84,111,111,110,32,66,111,111,109,32,72,97,114,109,111,110,121,32,50,48,124,115,116,97,114,116,117,112,124,98,112,121,124,49,34
T: 18:22:58.233 ByteArray Data: $"Toon Boom Harmony 20|startup|bpy|1"
T: 18:22:58.234 ByteArray Length: 39

It adds a double byte (length 38 vs 39, and its because the first character with charcode 129) to the QByteArray and it breaks the websocket frame format that we send to the browser. I can fix it removing the first byte of the QByteArray before sending it through the socket but its weird and we should check or put conditions in every places where we use QByteArrays because we dont know its behaviour.

I know you have implemented a QT version into Harmony and the bug is probably from QT and not from Harmony but could you check/test this kind of things when you release a version to select a good release of QT??

Best Regards
L