Got more questions? Find advice on: SQL | XML | Regular Expressions | Windows
in Search
Welcome to AspAdvice Sign in | Join | Help

C# Nuggets

Making Wrong Code Error on Compile

Joel Spolsky has written an article called Making Wrong Code Look Wrong where he posits the claim that Hungarian notation (more precisely, Apps Hungarian) is still useful in modern day programming. Joel is wrong.

Joel uses the example of HTML Encoding user input when writing output to a web page to prevent cross-site scripting attacks. Basically, he states that every encoded string should have an 's' prefix while unencoded strings should have a 'us' prefix. What he is doing is encoding type by convention, rather than using the power of a statically typed language to find the errors for him. What Joel needs is a SafeString class:

class SafeString {
 private string _text;
}
and this SafeString should have an implicit conversion to and from String: 
 public static implicit operator SafeString(string s) {
  return new SafeString(s);
 }
 public static implicit operator String(SafeString s) {
  return s._text;
 }
and a way of adding already encoded strings into a SafeString:
 public SafeString(string text, bool encoded) {
  if(encoded) {
   _text=text;
  } else {
   _text=HttpUtility.HtmlEncode(text);
  }
 }
As a simple test, I wrote a Console App to exercise this class:
 static void Main(string[] args) {
  SafeString name=args[0];
  SafeString prefix=new SafeString("Your <B>name</B> is:", true);
  prefix+=name;
  Console.WriteLine(prefix);
 }

Let's run this to see what we get:

rbirkby@tm-linux:~/svn/Experimental/SafeString $ mono safestring.exe 'Richard'
Your <B>name</B> is:Richard

rbirkby@tm-linux:~/svn/Experimental/SafeString $ mono safestring.exe 'Richard<SCRIPT>alert(“xss“)</SCRIPT>'
Your <B>name</B> is:Richard&lt;script&gt;alert(“xss“)&lt;/script&gt;

Lo and behold, we have a solution without Hungarian and in fact does it better than any coding convention could. If we wanted, we could create a new Response.Write() statement which only accepts a SafeString. In which case, the compiler is statically checking that we have correctly encoded all strings. The full code is:

using System;
using System.Web;
class SafeString {
 private string _text;
 public SafeString(string text, bool encoded) {
  if(encoded) {
   _text=text;
  } else {
   _text=HttpUtility.HtmlEncode(text);
  }
 }
 public SafeString(string text) : this(text, false) {}
 public static implicit operator SafeString(string s) {
  return new SafeString(s);
 }
 public static implicit operator String(SafeString s) {
  return s._text;
 }
 public static SafeString operator +(SafeString s1,SafeString s2) {
  s1._text += s2._text;
  return s1;
 }
 
}
class Test {
 static void Main(string[] args) {
  SafeString name=args[0];
  SafeString prefix=new SafeString("Your <B>name</B> is:", true);
  prefix+=name;
  Console.WriteLine(prefix);
 }
}
Sponsor
Published Wednesday, May 11, 2005 5:41 PM by rbirkby
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

rbirkby said:

Well I would say Joel has his point. There are a couple of other factors involved. For example:

for (int i=0; i<100000000; i++)
SafeString name = arg[0];

would probably run much slower than

for (int i=0; i<100000000; i++)
string name = arg[0];

Granted that this is an extremity, you can still see the point that I'm trying to make.

June 2, 2005 6:50 PM
 

rbirkby said:

Looks like premature optimization to me. Until you can prove that the expense of SafeString is causing a performance problem WHERE IT MATTERS, you're better off being safe & slow than fast & dangerous.
June 5, 2005 2:33 AM

Leave a Comment

(required) 
(optional)
(required) 
Enter the code you see below

Submit