The Problem
We had developed a class that contained an internal flag that would be set if a specific property on the class was set. The class would perform different logic based on whether or not the flag was set. In our testing we found that this internal flag was getting set in a scenario where it should not have been set. We verified that the code path executed in our test scenario would not explicitly set the property, but the flag was getting set.
Through a little investigation we determined that the Set property procedure for the property was being executed, even though we never explicitly set this property in our code. After a little more digging we discovered that this class’s property was being passed in to a procedure as the argument for a ByRef parameter.
What VB.NET Does
It appears that VB.NET basically does the following anytime an object property is used as an argument for a ByRef parameter:
1. VB.NET calls the Get property procedure for the object property that is being used as the argument for a ByRef parameter and stores it in a local variable. This is the same thing that happens when an object property is used as the argument for a ByVal parameter.
2. VB.NET will then execute the code in the procedure. Any Get or Set operations performed on the ByRef parameter will be executed against this local variable rather than the object property.
3. When the procedure has finished executing, VB.NET will set the object property’s value to the local variable by calling the Set property procedure for that object property. This will occur even if the local variable associated with the ByRef parameter was never set. If this were a ByVal parameter, this set operation would not occur.
This technique for handling object properties used as arguments for ByRef parameters seems reasonable, but if you are not aware that this is how VB.NET handles this situation, you can find yourself in trouble. In our case we had logic associated with the class’s property being set and we assumed the property would only be set if the ByRef parameter was set. Unfortunately, this is not how VB.NET was implemented by Microsoft, so we had to modify our code to accommodate the actual behavior of VB.NET.
What C# Does
Out of curiosity, I wanted to see if C# exhibited the same behavior as VB.NET, so I wrote a simple application to duplicate what we were doing in our VB.NET code. When I tried to compile the application, the following error occurred:
error CS0206: A property or indexer may not be passed as an out or ref parameter
It appears that the C# development team, when faced with the same technical issue, decided to inform the developer that he or she could not do what they were trying to do by raising a compiler error. In contrast, the VB.NET group provided the desired functionality, but implemented it in a way that is not necessarily intuitive.
Personal Opinion
I personally prefer the C# approach for handling this issue, but I understand why VB.NET works the way it does.
Lesson Learned
It is best to avoid using an object’s property as the argument for a ByRef parameter in VB.NET.
Friday, July 27, 2007
Friday, June 01, 2007
Possible Security Issue in IE on Windows XP
Conventional wisdom states that users should use non-administrative accounts for day-to-day usage on Windows XP machines to minimize exposure to malware. Windows XP even has a nice feature where an application can be executed using another user’s credentials if that application needs to run with special privileges.
An example of something that cannot be done with a non-administrative account is using Windows Update. To use Windows Update a user will typically right-click on the Internet Explorer (IE) icon, select Run As, and enter the credentials of an administrative account.
If that IE window is left open and a user clicks on a URL that appears in an e-mail message, the page will appear in the IE window with the administrative privileges instead of an IE window running as the user that is logged in. This would be very bad if the page that was loaded contained malware.
I expected Windows would open the URL in an IE window running under the logged-in users credentials. Unfortunately, IE opens the URL in the most recently opened IE window, even if that IE window is running under a different user’s credentials. This seems like a security issue to me.
An example of something that cannot be done with a non-administrative account is using Windows Update. To use Windows Update a user will typically right-click on the Internet Explorer (IE) icon, select Run As, and enter the credentials of an administrative account.
If that IE window is left open and a user clicks on a URL that appears in an e-mail message, the page will appear in the IE window with the administrative privileges instead of an IE window running as the user that is logged in. This would be very bad if the page that was loaded contained malware.
I expected Windows would open the URL in an IE window running under the logged-in users credentials. Unfortunately, IE opens the URL in the most recently opened IE window, even if that IE window is running under a different user’s credentials. This seems like a security issue to me.
Friday, May 18, 2007
.NET Left & Right Replacements
Back in the days of VB6 there were two trusty functions that programmers could rely on to truncate string:
All silliness aside, there is a simple way to reproduce the functionality of the
In VB6 if you had a three-character string called TestString and called
I colleague of mine came up with the following way to reproduce the functionality of the old VB6
The old VB6
Left
and Right
. These functions live on in the .NET Framework, but they live in the dreaded Microsoft.VisualBasic namespace, a namespace both shunned and feared by many. But do not loose hope, fair .NET programmer, for there is a “pure” way to easily reproduce the functionality of the Left
and Right
function with out resorting to the Microsoft.VisualBasic namespace methods.All silliness aside, there is a simple way to reproduce the functionality of the
Left
and Right
functions using non-Microsoft.VisualBasic namespace methods. The typically answer to this question is to use the Substring method, but the Substring
method requires to use valid startIndex
and length
arguments.In VB6 if you had a three-character string called TestString and called
Left(TestString, 5)
, you would get your three-character string back. In .NET if you were to have this same string and call TestString.Substring(0, 5)
method, you would get a ArgumentOutOfRangeException exception.I colleague of mine came up with the following way to reproduce the functionality of the old VB6
Left
function: TestString.Substring(0, Math.Min(5, TestString.Length))
The old VB6
Right
function can be reproduced by using the following: TestString.Substring(TestString.Length – Math.Min(5, TestString.Length), Math.Min(5, TestString.Length))
Subscribe to:
Posts (Atom)