Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. Subtle but Deadly ...

Subtle but Deadly ...

Scheduled Pinned Locked Moved Clever Code
c++graphicsdata-structuresbusiness
15 Posts 6 Posters 34 Views 1 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.
  • Z Offline
    Z Offline
    Zac Howland
    wrote on last edited by
    #1

    A few years ago, I wrote a function that dealt with creating an array of integers. There were some functional requirements that prohibited use of STL, so the function had to be written using primitive types. The following is basically what it looked like:

    int* CopySetAndDoSomething(int* ia, int size)
    {
    	int* pRet = new int[size];
    	memcpy(pRet, ia, size);
    	for (int i = 0; i < size; ++i)
    	{
    		pRet[i] += 5;
    	}
    	return pRet;
    }
    

    Now, the requirements specified that ia would always be non-null and size would always be >0. However, the method was then used by someone else in an MFC application where a vector was passed in with a size of 0. This yielded interesting results in Windows.

    If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

    P N S L 4 Replies Last reply
    0
    • Z Zac Howland

      A few years ago, I wrote a function that dealt with creating an array of integers. There were some functional requirements that prohibited use of STL, so the function had to be written using primitive types. The following is basically what it looked like:

      int* CopySetAndDoSomething(int* ia, int size)
      {
      	int* pRet = new int[size];
      	memcpy(pRet, ia, size);
      	for (int i = 0; i < size; ++i)
      	{
      		pRet[i] += 5;
      	}
      	return pRet;
      }
      

      Now, the requirements specified that ia would always be non-null and size would always be >0. However, the method was then used by someone else in an MFC application where a vector was passed in with a size of 0. This yielded interesting results in Windows.

      If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

      P Offline
      P Offline
      Paul Conrad
      wrote on last edited by
      #2

      How come ia isn't checked to be zero length? I would test for that condition and return a value accordingly.

      Z 1 Reply Last reply
      0
      • Z Zac Howland

        A few years ago, I wrote a function that dealt with creating an array of integers. There were some functional requirements that prohibited use of STL, so the function had to be written using primitive types. The following is basically what it looked like:

        int* CopySetAndDoSomething(int* ia, int size)
        {
        	int* pRet = new int[size];
        	memcpy(pRet, ia, size);
        	for (int i = 0; i < size; ++i)
        	{
        		pRet[i] += 5;
        	}
        	return pRet;
        }
        

        Now, the requirements specified that ia would always be non-null and size would always be >0. However, the method was then used by someone else in an MFC application where a vector was passed in with a size of 0. This yielded interesting results in Windows.

        If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

        N Offline
        N Offline
        Nish Nishant
        wrote on last edited by
        #3

        This line memcpy(pRet, ia, size); may also be a little unsafe. If size bigger than ia's length - then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation.

        Regards, Nish


        Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
        Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

        P Z L 3 Replies Last reply
        0
        • N Nish Nishant

          This line memcpy(pRet, ia, size); may also be a little unsafe. If size bigger than ia's length - then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation.

          Regards, Nish


          Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
          Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

          P Offline
          P Offline
          Paul Conrad
          wrote on last edited by
          #4

          Nishant Sivakumar wrote:

          may also be a little unsafe. If size bigger than ia's length - then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation

          Yes, and he would have to add a check for that in the code.

          1 Reply Last reply
          0
          • P Paul Conrad

            How come ia isn't checked to be zero length? I would test for that condition and return a value accordingly.

            Z Offline
            Z Offline
            Zac Howland
            wrote on last edited by
            #5

            That was the fix ... but the precondition stated that 0 would never be entered, so it wasn't checked originally.

            If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

            J 1 Reply Last reply
            0
            • N Nish Nishant

              This line memcpy(pRet, ia, size); may also be a little unsafe. If size bigger than ia's length - then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation.

              Regards, Nish


              Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
              Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

              Z Offline
              Z Offline
              Zac Howland
              wrote on last edited by
              #6

              While that is certainly possible, it is hard to verify that the memory you are looking at is actually the size you specified. Many of the old C-style API methods work like this and expect you to pass in the correct size. If I could have used STL, it would have been much simpler and avoided both of those issues.

              If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

              1 Reply Last reply
              0
              • Z Zac Howland

                A few years ago, I wrote a function that dealt with creating an array of integers. There were some functional requirements that prohibited use of STL, so the function had to be written using primitive types. The following is basically what it looked like:

                int* CopySetAndDoSomething(int* ia, int size)
                {
                	int* pRet = new int[size];
                	memcpy(pRet, ia, size);
                	for (int i = 0; i < size; ++i)
                	{
                		pRet[i] += 5;
                	}
                	return pRet;
                }
                

                Now, the requirements specified that ia would always be non-null and size would always be >0. However, the method was then used by someone else in an MFC application where a vector was passed in with a size of 0. This yielded interesting results in Windows.

                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                S Offline
                S Offline
                Stuart Dootson
                wrote on last edited by
                #7

                Zac Howland wrote:

                int* pRet = new int[size]; memcpy(pRet, ia, size);

                Hmmm - strikes me there's a bug here as well (assuming sizeof(int) != 1) ? First line allocates size ints (i.e size * sizeof(int) bytes, second one copies size bytes. Should I just presume a missing '* sizeof(int)' in the memcmp line? :-)

                Z 1 Reply Last reply
                0
                • S Stuart Dootson

                  Zac Howland wrote:

                  int* pRet = new int[size]; memcpy(pRet, ia, size);

                  Hmmm - strikes me there's a bug here as well (assuming sizeof(int) != 1) ? First line allocates size ints (i.e size * sizeof(int) bytes, second one copies size bytes. Should I just presume a missing '* sizeof(int)' in the memcmp line? :-)

                  Z Offline
                  Z Offline
                  Zac Howland
                  wrote on last edited by
                  #8

                  Stuart Dootson wrote:

                  Should I just presume a missing '* sizeof(int)' in the memcmp line?

                  Actually, that is just a typo on my part. The correct size was passed (size * sizeof(int)).

                  If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                  1 Reply Last reply
                  0
                  • Z Zac Howland

                    A few years ago, I wrote a function that dealt with creating an array of integers. There were some functional requirements that prohibited use of STL, so the function had to be written using primitive types. The following is basically what it looked like:

                    int* CopySetAndDoSomething(int* ia, int size)
                    {
                    	int* pRet = new int[size];
                    	memcpy(pRet, ia, size);
                    	for (int i = 0; i < size; ++i)
                    	{
                    		pRet[i] += 5;
                    	}
                    	return pRet;
                    }
                    

                    Now, the requirements specified that ia would always be non-null and size would always be >0. However, the method was then used by someone else in an MFC application where a vector was passed in with a size of 0. This yielded interesting results in Windows.

                    If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                    L Offline
                    L Offline
                    led mike
                    wrote on last edited by
                    #9

                    Zac Howland wrote:

                    memcpy(pRet, ia, size);

                    shouldn't that be memcpy(pRet, ia, sizeof(int)*size);

                    led mike

                    Z 1 Reply Last reply
                    0
                    • N Nish Nishant

                      This line memcpy(pRet, ia, size); may also be a little unsafe. If size bigger than ia's length - then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation.

                      Regards, Nish


                      Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                      Currently working on C++/CLI in Action for Manning Publications. Also visit the Ultimate Toolbox blog

                      L Offline
                      L Offline
                      led mike
                      wrote on last edited by
                      #10

                      Nishant Sivakumar wrote:

                      may also be a little unsafe.

                      unsafe as far as security? Buffer overflow attacks requires the "target" buffer to be smaller than the memcpy.size argument which is not the case here.

                      Nishant Sivakumar wrote:

                      then it may try and access un-readable memory (may not be a common scenario) and then you get an access violation.

                      Even if you don't get an access violation (not very common on a read), you will get garbage data.

                      led mike

                      1 Reply Last reply
                      0
                      • L led mike

                        Zac Howland wrote:

                        memcpy(pRet, ia, size);

                        shouldn't that be memcpy(pRet, ia, sizeof(int)*size);

                        led mike

                        Z Offline
                        Z Offline
                        Zac Howland
                        wrote on last edited by
                        #11

                        Yep.

                        If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                        L 1 Reply Last reply
                        0
                        • Z Zac Howland

                          Yep.

                          If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                          L Offline
                          L Offline
                          led mike
                          wrote on last edited by
                          #12

                          :doh: premature posting :->

                          led mike

                          1 Reply Last reply
                          0
                          • Z Zac Howland

                            That was the fix ... but the precondition stated that 0 would never be entered, so it wasn't checked originally.

                            If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                            J Offline
                            J Offline
                            Jorgen Sigvardsson
                            wrote on last edited by
                            #13

                            Who called the function? You should've slapped them on their fingers for not living up to their promises. ;)

                            -- A Stern Warning of Things to Come

                            Z 1 Reply Last reply
                            0
                            • J Jorgen Sigvardsson

                              Who called the function? You should've slapped them on their fingers for not living up to their promises. ;)

                              -- A Stern Warning of Things to Come

                              Z Offline
                              Z Offline
                              Zac Howland
                              wrote on last edited by
                              #14

                              Jörgen Sigvardsson wrote:

                              Who called the function? You should've slapped them on their fingers for not living up to their promises

                              My boss. So, obviously the problem was in my code ... and not in the requirements that he wrote up. That said, I should have written it better to avoid this kind of behavior anyway, but you have to learn somehow right?

                              If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                              J 1 Reply Last reply
                              0
                              • Z Zac Howland

                                Jörgen Sigvardsson wrote:

                                Who called the function? You should've slapped them on their fingers for not living up to their promises

                                My boss. So, obviously the problem was in my code ... and not in the requirements that he wrote up. That said, I should have written it better to avoid this kind of behavior anyway, but you have to learn somehow right?

                                If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week Zac

                                J Offline
                                J Offline
                                Jorgen Sigvardsson
                                wrote on last edited by
                                #15

                                Yeah, but still? If the precondition was size != 0, what could you do? I do stuff like ASSERT(!"You're stupid!") to tell them like it is! :-D

                                -- Pictures[^] from my Japan trip.

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups