Passing immutable types by reference in Java and C#

To many, it should be obvious what the following code prints:

public static void main(String[] args){
     int x=0;
     SomeMethod(x);
     System.out.println(x);
}

protected static void SomeMethod(int x){
     x=1;
}

The code prints 0, because “int” is a native type and is passed by value. But, what if we replace “int” with “Integer”?

public static void main(String[] args){
     Integer x=0;
     SomeMethod(x);
     System.out.println(x);
}

protected static void SomeMethod(Integer x){
     x=1;
}

This is where a lot of people get confused. Integer is an object type, and will be passed by reference, but the program still prints 0. Why? Even though x is a reference to an object, Integer is an immutable type, and the assignment “x=1” is actually equivalent to “x=new Integer(1)”. This actually changes the value of x, rather than the value pointed to by x.

Fortunately this case is rarely the source of errors since it’s considered bad design to return values through parameters.

Although the above code is in Java, you will run into similar behavior with C# immutable types.

Does string interning in C# guarentee you only get one copy of a static value?

Of course the answer is no, otherwise it wouldn’t be a very interesting post. The concept of interning is an attempt to save memory by allocating static values which match exactly to the same memory location, without regard to where they’re used in the application. But here’s in instance where it doesn’t quite work.

The String.Empty constant just contains the value “”. So logic would say that every value in the following code would point to the exact same location:

        static void Main(string[] args) {
            String t = "";
            String t1 = String.Empty;
            String t2 = String.Empty;
            String t3 = "";
            Console.WriteLine(t + t1 + t2 + t3);
        }

But, if you look at the disassembly, you find that the two values for “” were interned to one location (0226303Ch), and the String.Empty values were interned to another (0226102Ch):

String t = "";
00000033  mov         eax,dword ptr ds:[0226303Ch] 
00000039  mov         esi,eax 
String t1 = String.Empty;
0000003b  mov         eax,dword ptr ds:[0226102Ch] 
00000040  mov         edi,eax 
String t2 = String.Empty;
00000042  mov         eax,dword ptr ds:[0226102Ch] 
00000047  mov         dword ptr [ebp-48h],eax 
String t3 = "";
0000004a  mov         eax,dword ptr ds:[0226303Ch] 
00000050  mov         dword ptr [ebp-4Ch],eax 

Protection against SQL injection attacks in PHP.

Early on PHP had no good methods for escaping SQL, and until recently didn’t support parameterized queries. As a result a lot of documentation covers SQL queries without really addressing the issue, and a lot of older PHP developers are unaware of the enhancements made to prevent this type of attack.

PHP 4.3 introduced mysql_real_escape_string which escapes all potentially “bad” characters which could cause unwanted results in your queries. The link contains examples of how to use the function.

PHP5 includes the MySQLi (MySQL Improved) extention which provides a more enhanced API for accessing MySQL. The mysqli_stmt_bind_param function allows you to use parameterized queries. The link to the function provides an example of how to use parameterized queries.

Parameterized queries are generally considered safer than escaped strings, but that’s only in theory. mysql_real_escape_string currently escapes all known bad characters, and the only thing that would make it unsafe would be for another bad character to be discovered. But parameterized queries will go through a more complicated code path, and thus, more likely to be affected by a coding bug. So there’s really no security related argument which favors one over the other.

Some great advanced JavaScript videos

Douglas Crockford of Yahoo has made some excellent JavaScript lecture videos. He covers how to work around the issues in JavaScript to make it more scalable and easier to work with. I’ve yet to even see a book or anything else which could be purchased for money which delves into the details of the language at a depth of what Crockford does.

Although they are videos, I found it easy to follow by just letting it play in the background while working on something else. Of course there are many times you must switch over to the video to see the code he’s referring to, so it wouldn’t work well on just an MP3 player.

Douglas Crockford: “The JavaScript Programming Language” 1 of 4

Douglas Crockford: “The JavaScript Programming Language” 2 of 4

Douglas Crockford: “The JavaScript Programming Language” 3 of 4

Douglas Crockford: “The JavaScript Programming Language” 4 of 4

Douglas Crockford: “Advanced JavaScript” (1 of 3)

Douglas Crockford: “Advanced JavaScript” (2 of 3)

Douglas Crockford: “Advanced JavaScript” (3 of 3)

Finding “dead time” in a database of start and end times.

The following snippet will find “dead time” (e.g. time where no events are scheduled) in a database:

    1 select distinct dateadd(s,-1,starttime) as deadtime,"start" from sometable t where
    2  0=(select count(*) from sometable u where u.starttime < t.deadtime and u.endtime > t.deadtime)
    3 union all
    4 select distinct dateadd(s,1,endtime) as deadtime,"end" from sometable t where
    5  0=(select count(*) from sometable u where u.starttime < t.deadtime and u.endtime > t.deadtime)
    6 order by deadtime

Updating Linux systems for 2007 Daylight Savings Time changes.

This works on most systems. First download the updated DST packages:
wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'

Extract and compile the utilities:

tar -zxvvf tzco*
tar -zxvvf tzda*
make

Now compile the data:

mkdir temp
./zic -d temp northamerica

Verify the new data file is correct:

./zdump -v temp/EST5EDT | grep 2007
/etc/localtime Sun Mar 11 06:59:59 2007 UTC = Sun Mar 11 01:59:59 2007 EST isdst=0
/etc/localtime Sun Mar 11 07:00:00 2007 UTC = Sun Mar 11 03:00:00 2007 EDT isdst=1
/etc/localtime Sun Nov 4 05:59:59 2007 UTC = Sun Nov 4 01:59:59 2007 EDT isdst=1
/etc/localtime Sun Nov 4 06:00:00 2007 UTC = Sun Nov 4 01:00:00 2007 EST isdst=0

Verify your old settings really are incorrect:

./zdump -v /etc/localtime | grep 2007
/etc/localtime.old Sun Apr 1 06:59:59 2007 UTC = Sun Apr 1 01:59:59 2007 EST isdst=0
/etc/localtime.old Sun Apr 1 07:00:00 2007 UTC = Sun Apr 1 03:00:00 2007 EDT isdst=1
/etc/localtime.old Sun Oct 28 05:59:59 2007 UTC = Sun Oct 28 01:59:59 2007 EDT isdst=1
/etc/localtime.old Sun Oct 28 06:00:00 2007 UTC = Sun Oct 28 01:00:00 2007 EST isdst=0

Now install the new file:

cd /etc
mv localtime localtime.old
cp ~/asdf/temp/EST5EDT localtime
#Verify correct installation:
./zdump -v /etc/localtime | grep 2007
/etc/localtime Sun Mar 11 06:59:59 2007 UTC = Sun Mar 11 01:59:59 2007 EST isdst=0
/etc/localtime Sun Mar 11 07:00:00 2007 UTC = Sun Mar 11 03:00:00 2007 EDT isdst=1
/etc/localtime Sun Nov 4 05:59:59 2007 UTC = Sun Nov 4 01:59:59 2007 EDT isdst=1
/etc/localtime Sun Nov 4 06:00:00 2007 UTC = Sun Nov 4 01:00:00 2007 EST isdst=0

Note, for some reason zdump will give incorrect output if you are in the same directory as the file you’re attempting to dump. For example “zdump -v localtime | grep 2007” won’t return anything. I also ran into some cases where specifying the path to the file as temp/EST5EDT didn’t work either, so try to always specify the full path to the file: “zdump -v /etc/loclaltime …”.

How to query accross servers using MS SQL Server.

Sometimes you need to query across servers, even servers of different type such as doing a table join from MySQL to Oracle. I’m going to show you two ways you could do this if you have access to an SQL Server. There are ways to do this with other servers, and there are more than two ways to do this in SQL Server, but I’m only covering two methods both using SQL Server here.

Using linked servers:

Execute the following two stored procedures (you will need SA privileges):

exec sp_addlinkedserver @server='server.asdf.com';
exec sp_addlinkedsrvlogin @rmtsrvname='server.asdf.com',@useself=false, @rmtuser='yourusername', @rmtpassword='yourpassword';

Test the connection:

select top 1 * from [server.asdf.com].somedatabase.dbo.sometable;

Using OpenDataSource:

No setup is needed for this method, you just need to alter the FROM clause of your SQL statement:

select * from OpenDataSource('SQLOLEDB','Data Source=server.asdf.com;User ID=yourusername;Password=yourpassword').somedatabase.dbo.sometable;

Comments

There are a few notable differences between the two methods:

  • Using OpenDataSource does not require any extra privileges beyond execute query, where Linked Servers requires admin privileges.
  • Using OpenDataSource requires that the username and password be accessible in some way to your code. Linked Servers hides the login credentials, but will allow anyone with SELECT privileges to the server to authenticate and run queries on any linked servers as the user specified when sp_addlinkedsrvlogin was ran. It’s up to you to determine which is more secure for your environment.

Note, the examples I’ve provided use SQL Server as the linked server, but it’s possible to use any database which you have an ODBC driver for. The Microsoft documentation for each method will help you figure out exactly how if you can’t figure it out.