Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QByteArray not initializing
Qt 6.12 LTS is out! See what's new in the release blog

QByteArray not initializing

Scheduled Pinned Locked Moved Solved General and Desktop
40 Posts 7 Posters 18.5k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • aha_1980A aha_1980

    @mzimmers said in QByteArray not initializing:

    @aha_1980 not sure what you mean by "an unequal number of chars".

    strlen(Mac8) == 65

    Your loop is iterating with steps of two. So you're reading over the end of Mac8 with sscanf().

    I'm not sure what QByteArray::fromHex() will do with this invalid input, but most likely it will not crash. (If it does, we create a bugreport).

    mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #15

    @aha_1980 this crash is occurring on the second iteration through the loop, so I don't think it's an array/string overrun.

    mrjjM 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #16

      Oddly enough i dont crash here
      it just converts to 32 values each time.

      alt text

      mzimmersM 1 Reply Last reply
      0
      • mzimmersM mzimmers

        @aha_1980 this crash is occurring on the second iteration through the loop, so I don't think it's an array/string overrun.

        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #17

        @mzimmers
        Hi
        Can you try
        // QCoreApplication a(argc, argv);
        // a.exec();
        and just return 0;

        You are not sending it a close signal so i think crash is due to killing it with debugger.

        At least i cannot crash it without running the coreapp and exec().

        1 Reply Last reply
        0
        • mrjjM mrjj

          Oddly enough i dont crash here
          it just converts to 32 values each time.

          alt text

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #18

          @mrjj yeah, I'm pretty sure my loops are OK. I honestly don't know what's going on -- maybe some weird bug in the constructor.

          I removed the core app stuff...same results.

          I think I'll implement aha_1980's suggestion. I took another look, and it's a lot simpler than this. I'll report back on how I do with it.

          mrjjM 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @mrjj yeah, I'm pretty sure my loops are OK. I honestly don't know what's going on -- maybe some weird bug in the constructor.

            I removed the core app stuff...same results.

            I think I'll implement aha_1980's suggestion. I took another look, and it's a lot simpler than this. I'll report back on how I do with it.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #19

            @mzimmers
            Ok. i checked the loop and its 64 in length and result is 32 in bytearray.
            no crashes at any time.
            Very odd then.
            Im on 64 bit.

            1 Reply Last reply
            0
            • mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #20

              I'm on Windows 10, using MinGW, FWIW. Just tried null terminating the string myself, and still bombs in the loop (though aha's suggestion works).

              mrjjM 1 Reply Last reply
              0
              • mzimmersM mzimmers

                I'm on Windows 10, using MinGW, FWIW. Just tried null terminating the string myself, and still bombs in the loop (though aha's suggestion works).

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #21

                @mzimmers
                Hmm visual studio here.
                Maybe its related to mingw.
                I will try tomorrow at work with mingw and see.
                I dont like when crashes are not reproducible.

                1 Reply Last reply
                1
                • mzimmersM mzimmers

                  @mrjj here's the code in its entirety:

                  #include <QByteArray>
                  #include <QDebug>
                  #include <QCoreApplication>
                  #include <QMessageAuthenticationCode>
                  #include <QCryptographicHash>
                  
                  int test(char *key, char *txt, char *mac);
                  
                  int main(int argc, char *argv[])
                  {
                      QCoreApplication a(argc, argv);
                  
                      char  Key8[] =          "60e431591ee0b67f0d8a26aacbf5b77f"  //  arbitrary key
                                              "8e0bc6213728c5140546040f0ee37f54";
                      char  Txt8[] =                                              //  Len = 1054 BYTES
                                  "e5098b6a0b1cfc57c6a76537104a39c48baecb15c6bbb46fbb0b745f9c9e5c05"
                                  "cfcfabb33786f7b7b5b0ce74eeec9eb84f87d2494fab3ec1f4d3bd9c99821890"
                                  "ee352a1d40964264fbf2c93c6ded2583cc75dcb27bf4fdb489cabcf97bfa5cc6"
                                  "4b2352cfb0b3a707a0579eb713b697cd0b5e3377d1feb9f181d7b89cc86dee4f"
                                  "ed8269f10e44ec48adc6940c6badbb40122c1dc2d9323920e4e1fbad0b4397d4"
                                  "dc38b8ade3b3dace2926f464fa3b5b82ebc5e3b81cf647e8bbd2cb55c9e31ffd"
                                  "212f8729b66739421c6106e64ac83d3b9e13cd8321b3a9f10d9171bb8cb74e71"
                                  "c34d1e8d0fc8d14b8e5e12bbe2bd2a1431fc224b70d228e4e2063509db26ecd9"
                                  "ca7cc402763e69928805600a4a80eab4ae6a2c3792b98c6942195e643f98c0dc"
                                  "3fa3c2b07431cbbe113e38fc0b7b45c51c4431700ed29d2736b236f63f759323"
                                  "29aa60be9009bd7832f1e1b9ac1503ec84727a1e6c8423c7c5b903e763262d55"
                                  "9078e654532e0868f206a468b5b5ebd3eddb4f673536e5f0f8160e5f3311561b"
                                  "7cf79c9c440974355965c931aec5c7225f69f776f052ac4bd6b19f85389fd61d"
                                  "f60ecabbeb00c8886ff7983d20ac5d81e303bc71253f40806772fd81f9387402"
                                  "05a5b7dcd07cce083da258b493d275967f91e4815d656936b342727cfe45f973"
                                  "b2a5ac257ce64c5eca4f53be8d9fd90c3dfcb8cd1e2cef15c307449ed02c2e17"
                                  "04f4f1be76a40b311ee7cf81987b5089252a807ef3fc99c79eabbc0ef657d897"
                                  "037bced04620d32a425015283bcea1b53e0484bb613d30f14c1422f5f82cc29a"
                                  "b7228b8375c06bf13d746dd9ff00953a90720badf2577d3ed62cbe7a5f15b3c9"
                                  "29d26ffe8aee9d2d17391ebc6a79f4bd235d5f7b2db2455343d9d7c6b27972cc"
                                  "6071c36a0d112f86d98972fb06a186e900abc64e9ab653db9b05b70079c0c84a"
                                  "64e8cfee8690eaa68a4bafbb5be112632e46894ec2cc6e7ce697a4513d517deb"
                                  "3e20dbb37ed5963232671e27ef9f62d6b514f0a22c5a5dde2d77e7e184965958"
                                  "f5002fe17d47fbd5d9c407644d443ce89eff427360cae9aa788dc8d7d9f62439"
                                  "916f139f094ee035884cb29dfa396941f0eec9e8e782da88cdc18e5bc1d9a535"
                                  "1b57ce15ac520ffa47e666f87fe5b18ab3c8cb2a48ecf81f36fb8397c6a7a5f5"
                                  "9a9fa96cedbb4ecd1c7a6d9d65afdb6bef7791600b6e0a18ba23edb06fc9ec21"
                                  "162feccc54f2665611f10db53401b18bade263b3b972da1a612115d144a54260"
                                  "97efdf5c6a5d1f3c2d318f687242f993f5f1884bd95f2ece34dd4320cea46f5a"
                                  "26c7c945b665402778233bdda9d97c2acd8c4a4ff39dcfdc3a3fbfc5942e3ab8"
                                  "ca9ff4aec17293c1fbaf583d603002f93f9befe8909485eb7c30d0e91fac6c22"
                                  "8c5fa6c011eddeafbdbe30af20ae53a85206c03d37ac17a30096bfb4f584cd3f"
                                  "72ef28a3303cea9cc636095c70bb36de0eb50577704d4faed05bd54da020";
                  
                      char  Mac8[] =                          //  HMAC_SHA256 7.3728=410ms 18.4320=
                                  "4a0ce2f8ffca9e77443e661c88ccdc04ba6ac9bb901642fadae7fe8e4c2d50f7";
                  
                      test(Key8, Txt8, Mac8);
                      return a.exec();
                  }
                  
                  int test(char *key, char *txt, char *mac)
                  {
                      QByteArray qKey;
                      QByteArray qTxt;
                      QByteArray qMac;
                      uint8_t c;
                      char *p;
                      uint32_t n;
                  
                      n = strlen(txt);
                      for (uint32_t i = 0; i < n; i += 2)
                      {
                          p = txt + i;
                          sscanf(p, "%2x", (int *) &c);
                          qTxt.append((char) c);
                      }
                  
                      n = strlen(key);
                      for (uint32_t i = 0; i < n; i +=2)
                      {
                          p = key + i;
                          sscanf(p, "%2x", (int *) &c);
                          qKey.append((char) c);
                      }
                  
                      n = strlen(mac);
                      for (uint32_t i = 0; i < n; i +=2)
                      {
                          p = mac + i;
                          sscanf(p, "%2x", (int *) &c);
                          qMac.append((char) c);
                      }
                  
                      QMessageAuthenticationCode auth(QCryptographicHash::Sha256, qKey);
                      auth.addData(qTxt, 1054);
                      qMac = auth.result();
                  
                      return (strcmp(qMac.data(), mac) == 0);
                  }
                  

                  qTxt and qKey work perfectly.

                  EDIT:

                  I'm aware that the strlen calls might not work right all the time, but they seem to be OK in this example. There's something wrong with my qMac variable, at least in the eyes of the debugger.

                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by JonB
                  #22

                  @mzimmers said in QByteArray not initializing:

                  @mrjj here's the code in its entirety:

                  uint8_t c;
                  
                  sscanf(p, "%2x", (int *) &c);
                  

                  c holds a 8-bit int, right? Firstly that's not right for (int *) &c, and secondly look at sscanf("%2x", it will expect the address of a whole int (32-bit? 64-bit?) to store its result. So you're overwriting the local stack space, hence possible crashing? Or, uint8_t is allocated on an odd address boundary, which won't be good.

                  Make c be a proper int, or fix your sscanf.

                  Your understanding of QByteArray is fine, but not of scanf :-)

                  Also, if you use QByteArray::fromHex(), you won't need to use sscanf :)

                  mzimmersM mrjjM 2 Replies Last reply
                  3
                  • JonBJ JonB

                    @mzimmers said in QByteArray not initializing:

                    @mrjj here's the code in its entirety:

                    uint8_t c;
                    
                    sscanf(p, "%2x", (int *) &c);
                    

                    c holds a 8-bit int, right? Firstly that's not right for (int *) &c, and secondly look at sscanf("%2x", it will expect the address of a whole int (32-bit? 64-bit?) to store its result. So you're overwriting the local stack space, hence possible crashing? Or, uint8_t is allocated on an odd address boundary, which won't be good.

                    Make c be a proper int, or fix your sscanf.

                    Your understanding of QByteArray is fine, but not of scanf :-)

                    Also, if you use QByteArray::fromHex(), you won't need to use sscanf :)

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #23

                    @JNBarchan the pointer should be OK, as far as I can see. Your point about the sscanf() overwriting the output buffer may be valid, though it's really odd that the first two loops worked fine.

                    JonBJ 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @mzimmers said in QByteArray not initializing:

                      @mrjj here's the code in its entirety:

                      uint8_t c;
                      
                      sscanf(p, "%2x", (int *) &c);
                      

                      c holds a 8-bit int, right? Firstly that's not right for (int *) &c, and secondly look at sscanf("%2x", it will expect the address of a whole int (32-bit? 64-bit?) to store its result. So you're overwriting the local stack space, hence possible crashing? Or, uint8_t is allocated on an odd address boundary, which won't be good.

                      Make c be a proper int, or fix your sscanf.

                      Your understanding of QByteArray is fine, but not of scanf :-)

                      Also, if you use QByteArray::fromHex(), you won't need to use sscanf :)

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #24

                      @JNBarchan
                      Thats a really good observation and might explain why
                      no crashing here 64bit. Completely overlooked it :)
                      alt text

                      JonBJ 1 Reply Last reply
                      3
                      • mzimmersM mzimmers

                        @JNBarchan the pointer should be OK, as far as I can see. Your point about the sscanf() overwriting the output buffer may be valid, though it's really odd that the first two loops worked fine.

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #25

                        @mzimmers said in QByteArray not initializing:

                        @JNBarchan the pointer should be OK

                        What pointer, and what do you mean by "OK"?

                        P.S. I can explain why it goes through sometimes and fails others, but it's going to mean quite a bit of typing, do you really want to know?

                        mzimmersM 1 Reply Last reply
                        0
                        • mrjjM mrjj

                          @JNBarchan
                          Thats a really good observation and might explain why
                          no crashing here 64bit. Completely overlooked it :)
                          alt text

                          JonBJ Online
                          JonBJ Online
                          JonB
                          wrote on last edited by
                          #26

                          @mrjj
                          If that sscanf supports %hhx that should work.

                          1 Reply Last reply
                          0
                          • JonBJ JonB

                            @mzimmers said in QByteArray not initializing:

                            @JNBarchan the pointer should be OK

                            What pointer, and what do you mean by "OK"?

                            P.S. I can explain why it goes through sometimes and fails others, but it's going to mean quite a bit of typing, do you really want to know?

                            mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #27

                            @JNBarchan in this line of code:

                                   sscanf(p, "%2x", (int *) &c);
                            

                            the address formed by the cast should be fine, as far as I can tell.

                            I agree the problem is in the sscanf. This line of code:

                                    sscanf(p, "%hhx", &c);
                            

                            compiles but doesn't work right (c keeps getting 0xff). I'm going to go with aha_1980's approach and call it a day.

                            Thanks to everyone who looked at this.

                            JonBJ 1 Reply Last reply
                            0
                            • mzimmersM mzimmers

                              @JNBarchan in this line of code:

                                     sscanf(p, "%2x", (int *) &c);
                              

                              the address formed by the cast should be fine, as far as I can tell.

                              I agree the problem is in the sscanf. This line of code:

                                      sscanf(p, "%hhx", &c);
                              

                              compiles but doesn't work right (c keeps getting 0xff). I'm going to go with aha_1980's approach and call it a day.

                              Thanks to everyone who looked at this.

                              JonBJ Online
                              JonBJ Online
                              JonB
                              wrote on last edited by
                              #28

                              @mzimmers said in QByteArray not initializing:

                              @JNBarchan in this line of code:

                                     sscanf(p, "%2x", (int *) &c);
                              

                              the address formed by the cast should be fine, as far as I can tell.

                              The address is indeed a valid address, but it points to an area reserved to hold one byte and you're storing 4 or 8 bytes there, which is very naughty! Hope you understand.

                              kshegunovK 1 Reply Last reply
                              4
                              • JonBJ JonB

                                @mzimmers said in QByteArray not initializing:

                                @JNBarchan in this line of code:

                                       sscanf(p, "%2x", (int *) &c);
                                

                                the address formed by the cast should be fine, as far as I can tell.

                                The address is indeed a valid address, but it points to an area reserved to hold one byte and you're storing 4 or 8 bytes there, which is very naughty! Hope you understand.

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #29

                                @JNBarchan said in QByteArray not initializing:

                                which is very naughty!

                                Buffer overflows - the pinnacle of C programming ... ;)

                                Read and abide by the Qt Code of Conduct

                                mzimmersM 1 Reply Last reply
                                0
                                • kshegunovK kshegunov

                                  @JNBarchan said in QByteArray not initializing:

                                  which is very naughty!

                                  Buffer overflows - the pinnacle of C programming ... ;)

                                  mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #30

                                  @kshegunov I expected the "%2x" in the sscanf to restrict output to one byte (2 hex characters), but I guess it doesn't work that way.

                                  kshegunovK 1 Reply Last reply
                                  0
                                  • mzimmersM mzimmers

                                    @kshegunov I expected the "%2x" in the sscanf to restrict output to one byte (2 hex characters), but I guess it doesn't work that way.

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #31

                                    Not really, no. There's no compile-time type checking with variadic functions (which scanf and related are). It will expect you to give it a proper integer to write to. But really your error is the cast itself. You can't cast pointers like this. You have a char on the stack and you cast its address to a int *. From there on the compiler will consider that this pointer is referencing an integer, meaning you have "hijacked" 3 bytes from the nearby variables in the stack. If you modify your code like this:

                                    uint8_t c, c2, c3, c4;
                                    // ...
                                    sscanf(p, "%2x", (int *) &c);
                                    // ...
                                    

                                    You'd discover that all those variables - c2, c3 and c4 are modified alongside your original c because sscanf overruns the given buffer and writes outside of it.

                                    Read and abide by the Qt Code of Conduct

                                    JonBJ 1 Reply Last reply
                                    4
                                    • JonBJ Online
                                      JonBJ Online
                                      JonB
                                      wrote on last edited by JonB
                                      #32

                                      The original code has:

                                          QByteArray qMac;
                                          uint8_t c;
                                      

                                      My guess is qMac is stored above c in the local stack. When you write to &c you cobble what's in qMac, so the bug doesn't show up till you reach the qMac loop. Then qMac.append((char) c); gets evaluated and crashes. Am I right?

                                      Behaviour could vary across 32/64 size and specific compiler allocation or register code generated.

                                      mzimmersM 1 Reply Last reply
                                      4
                                      • JonBJ JonB

                                        The original code has:

                                            QByteArray qMac;
                                            uint8_t c;
                                        

                                        My guess is qMac is stored above c in the local stack. When you write to &c you cobble what's in qMac, so the bug doesn't show up till you reach the qMac loop. Then qMac.append((char) c); gets evaluated and crashes. Am I right?

                                        Behaviour could vary across 32/64 size and specific compiler allocation or register code generated.

                                        mzimmersM Offline
                                        mzimmersM Offline
                                        mzimmers
                                        wrote on last edited by
                                        #33

                                        @JNBarchan that explanation makes sense. I'll have to brush up on how sscanf works (though I'd rather use something else) to avoid similar problems in the future.

                                        Thanks to all who participated.

                                        1 Reply Last reply
                                        1
                                        • kshegunovK kshegunov

                                          Not really, no. There's no compile-time type checking with variadic functions (which scanf and related are). It will expect you to give it a proper integer to write to. But really your error is the cast itself. You can't cast pointers like this. You have a char on the stack and you cast its address to a int *. From there on the compiler will consider that this pointer is referencing an integer, meaning you have "hijacked" 3 bytes from the nearby variables in the stack. If you modify your code like this:

                                          uint8_t c, c2, c3, c4;
                                          // ...
                                          sscanf(p, "%2x", (int *) &c);
                                          // ...
                                          

                                          You'd discover that all those variables - c2, c3 and c4 are modified alongside your original c because sscanf overruns the given buffer and writes outside of it.

                                          JonBJ Online
                                          JonBJ Online
                                          JonB
                                          wrote on last edited by
                                          #34

                                          @kshegunov said in QByteArray not initializing:

                                          uint8_t c, c2, c3, c4;
                                          // ...
                                          sscanf(p, "%2x", (int *) &c);
                                          // ...
                                          

                                          You'd discover that all those variables - c2, c3 and c4 are modified alongside your original c because sscanf overruns the given buffer and writes outside of it.

                                          @kshegunov Purely OOI, did you actually test this code? I was actually thinking, assuming local variables allocated down the stack in order they're encountered, you'd have to sscanf into c4 rather than c to get that behaviour from the way they're laid out...?

                                          kshegunovK 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt
                                          • Unsolved