Bug found in VB.net using New Byte call

  • Thread starter Thread starter Steve Mauldin
  • Start date Start date
S

Steve Mauldin

I came across an example in the MSDN documentation using RC2 encryption(the
link to the article is at the end of this message). When I tried it I had a
problem with getting back the same length string that I sent into it. After
working on Debugging the code I found two problems. One was in the
statement fromEncrypt = New Byte(encrypted.Length) {} where both
FromEncrypt and encrypted are both byte arrays and encrypted's length is 24.
Once this statement is executed FromEncrypt's length is 25. This introduces
an extra null byte onto fromEncrypt's array. The other problem, which maybe
just a misunderstanding on my part about the ASCIIEncoding object, is on
the statement roundtrip = textConverter.GetString(fromEncrypt). This call
to the ASCIIEncoding object, using a byte array with multiple 0 bytes on the
end of the array, results in a string with null characters attached on the
end. My undertanding is that strings are null terminated. When I pass a
byte array containing multiple 0 bytes on the end I would expect a byte to
string converter to remove nulls off the end of the byte array. As it
happened I had to write code to redim the byte array to remove the nulls
before I got back the same string that I sent. I hope this post helps
others who try to use this example in the future and I also hope Microsoft
reads these things so they know they have a problem in the New Byte(length)
method.
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfsystemsecurit
ycryptographyrc2cryptoserviceproviderclasstopic.htm
 
Steve Mauldin said:
I came across an example in the MSDN documentation using RC2 encryption(the
link to the article is at the end of this message). When I tried it I had a
problem with getting back the same length string that I sent into it. After
working on Debugging the code I found two problems. One was in the
statement fromEncrypt = New Byte(encrypted.Length) {} where both
FromEncrypt and encrypted are both byte arrays and encrypted's length is 24.
Once this statement is executed FromEncrypt's length is 25

IIRC, for VB, when you create an array of 25, it creates a 26 elements
(0..25) and not the 25 a C* programmer would expect (0..24).
 
Steve Mauldin said:
I came across an example in the MSDN documentation using RC2 encryption(the
link to the article is at the end of this message). When I tried it I had a
problem with getting back the same length string that I sent into it. After
working on Debugging the code I found two problems. One was in the
statement fromEncrypt = New Byte(encrypted.Length) {} where both
FromEncrypt and encrypted are both byte arrays and encrypted's length is 24.
Once this statement is executed FromEncrypt's length is 25. This introduces
an extra null byte onto fromEncrypt's array.

I'm not sure I follow you here - could you produce a short but complete
example?
The other problem, which maybe
just a misunderstanding on my part about the ASCIIEncoding object, is on
the statement roundtrip = textConverter.GetString(fromEncrypt). This call
to the ASCIIEncoding object, using a byte array with multiple 0 bytes on the
end of the array, results in a string with null characters attached on the
end. My undertanding is that strings are null terminated. When I pass a
byte array containing multiple 0 bytes on the end I would expect a byte to
string converter to remove nulls off the end of the byte array.

No, Unicode 0 is a perfectly valid character. Strings happen to be
stored in a null-terminated way in the CLR so that interop is easy, but
they aren't *conceptually* null-terminated, and the null character is
available as a character. A string is just a sequence of characters,
and has a length -
As it
happened I had to write code to redim the byte array to remove the nulls
before I got back the same string that I sent.

If you're having to do that, it sounds like something has gone wrong
earlier on. However, calling String.Replace ("\0", "") would do the job
otherwise.
I hope this post helps
others who try to use this example in the future and I also hope Microsoft
reads these things so they know they have a problem in the New Byte(length)
method.
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfsystemsecurit
ycryptographyrc2cryptoserviceproviderclasstopic.htm

In future, giving web links to MSDN is considerably more helpful,
otherwise people have to have the same version of MSDN installed as
you. However, having had a look at the MSDN documentation it certainly
doesn't look like well written code (there's no need to create a new
instance of ASCIIEncoding, for instance, declaring all the byte arrays
early on is horrible), reading from a stream and assuming the whole
length will be reading in one go is unreliable, etc. And indeed, the
supposedly round-tripped data *isn't* the same (try just writing the
length of the two strings out and you'll see the difference).
Basically, it's a nasty bit of code, but I don't think all of the
problems you have with it are necessary the same as the real problems
in the code.
 
Steve,
As Ayende stated. Arrays in VB.NET use the upper bound when defining arrays,
rather then the number of elements.

So:

fromEncrypt = New Byte(encrypted.Length) {}

Will create an array with an extra element.

While:

fromEncrypt = New Byte(encrypted.Length - 1) {}

Will create an array with the same number of elements.

Apparently this was done to simplify migrating from VB6 to VB.NET.

Hope this helps
Jay
 
Back
Top