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 37 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 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