Interesting validation framework

The most important part of developing secure (and robust) systems is to validate all input that comes from the outside (and for large systems, even between components). However, writing validation code isn’t usually very fun, and so like many other good practices, validating your input sometimes is neglected. If you develop in ASP.NET or Winforms, there are some validation controls that help you a little bit, but they don’t provide out-of-the box protection against XSS attacks, SQL injection, UTF-8 canonicalization problems and so on. To guard against things like that you need to write your own validation code.

In this article, Mathew Nolton describes a validation framework that lets you use custom attributes to do most of the heavy lifting, essentially providing declarative validation. This stuff is very cool, and another fine example of just how useful custom attributes in .Net can be.

I think the following method signature gives you an idea of how it works:

public void SomeMethod ( 
		[RegExAttribute("[a,e,i,o,u]",RegexOptions.None)]
                   string someParameter)


Together with some boilerplate code (which could be autoinserted by your editor), this ensures that if someParameter ever contains anything but the letters a,e,i,o,u, a ValidationException is thrown.

7 weeks to go

I still do train for this year’s Stockholm
Marathon
, but I haven’t recorded my progress
in a long time. I’ve more or less given up on the official training program, and just try to run my regular 9 km run three times a week, with the occasional
half-marathon now and then. Since spring has arrived,
I now can run outside, which really is better than the treadmill. I’m close to my goal pace on
the 9 km course, but then there’s the small problem of keeping that pace for an additional 33 km…

Old permalinks sort of not working

It seems that there is some sort of subtle bug in my import script. If there are more than one entry per day, permalinks to the earliest item turn up an empty page. Here’s an example. The entry as such is sort-of-working, as you can see in this date view, but the permalink (and edit/delete links as well) simply turn up empty pages. The problem doesn’t manifest itself with entries created by dasblog, so I think the bug is in my script.

Stuff to add to your wishlist


Here’s the real reason why I wanted the blog up and running: So I could tell you all about the PlusDeck.


The PlusDeck 2 is a full-logic cassette deck for your PC. Use it to archive your old cassette tapes of 80s hair bands into digital media files for playback on your PC. Or better yet, archive your favorite audio files or streams onto cassette – perfect for playback in your ’78 Midget that is still not sporting an in-dash CD player.

Stuff now imported into dasBlog

I went ahead and wrote a little C# program to convert a sharpreader-style cache RSS file into a set of dasBlog-compatible dayentry files. One little problem surfaced in that while BlogX used a url + random GUID for each entry’s guid, dasBlog uses only a random guid. This will have the effect of a bunch of entries (15, to be exact) appearing as new in your RSS aggregators. Sorry about that as well.

Anyway, if someone needs to do something similar, here’s the code I used. It expects a sharpreader-generated file named ”backup.xml” in its working directory (look for a suitable file in %USERPROFILE%\Application Data\SharpReader\Cache and rename it), and if you’re not in the CEST timezone, you should probably fix the line with the FIXME comment.

using System;
using System.Xml;

namespace DasBlogImport
{
  class Importer
  {
    static private void addElementToEntry(XmlDocument doc, 
                                          XmlElement entry, 
                                          String elementName, 
                                          String elementValue) 
    {
      XmlElement e = doc.CreateElement(elementName);
      e.InnerText = elementValue;
      entry.AppendChild(e);
    }
    [STAThread]
    static void Main(string[] args)
    {
      XmlDocument doc = new XmlDocument();
      doc.Load("backup.xml");
      XmlNodeList nodeList = doc.GetElementsByTagName("Items");
      XmlNode element;
      XmlNode entries = null;
      String lastDate = String.Empty;
      XmlDocument dayentry = null;

      foreach  (XmlNode item in nodeList) 
      {
        element = item.SelectSingleNode("PubDate");
        String date = element.InnerText.Substring(0,10);
        

        if (date != lastDate) 
        {
          // flush the entries for the current day, and start a new document
          if (dayentry != null)
            dayentry.Save(lastDate+".dayentry.xml");
          dayentry = new XmlDocument();
          dayentry.LoadXml("");
          XmlElement root = dayentry.DocumentElement;
          element = dayentry.CreateElement("Date");
          element.InnerText = date + "T02:00:00.0000000+02:00"; // FIXME: If you're not in the CEST timezone, you probably want to change this
          root.AppendChild(element);
          entries = dayentry.CreateElement("Entries");
          root.AppendChild(entries);
          lastDate = date;
        }
        XmlElement entry = dayentry.CreateElement("Entry");
        entries.AppendChild(entry);

        addElementToEntry(dayentry, entry, "Content",        item.SelectSingleNode("Description").InnerText);
        addElementToEntry(dayentry, entry, "Created",        item.SelectSingleNode("PubDate").InnerText);
        addElementToEntry(dayentry, entry, "Modified",       item.SelectSingleNode("PubDate").InnerText);
        String guid = item.SelectSingleNode("Guid").InnerText;
        addElementToEntry(dayentry, entry, "EntryId",        guid.Substring(guid.Length-36,36)); // 36 = the length of a 128-bit GUID in standard string form
        addElementToEntry(dayentry, entry, "Description",    String.Empty);
        addElementToEntry(dayentry, entry, "Title",          item.SelectSingleNode("Title").InnerText);
        if (item.SelectSingleNode("Subject") != null)
          addElementToEntry(dayentry, entry, "Categories",   item.SelectSingleNode("Subject").InnerText);
        else
          addElementToEntry(dayentry, entry, "Categories",   String.Empty);

        addElementToEntry(dayentry, entry, "IsPublic",       "true");
        addElementToEntry(dayentry, entry, "ShowOnFrontPage","true");
        addElementToEntry(dayentry, entry, "Crossposts",     String.Empty);
      }
    }
  }
}

Hard disks suck

So, my spiffy SATA hard disk crashed. I had most important stuff backed up, but sadly not the blog postings. I do have all the content in the form of a sharpreader cache file, so the stuff will come back, but it seems that all images and, more importantly, all comments, are lost. Sorry about that. New backup routines are established…

Now I have to write a little program to parse the cache file (which seem to be straight RSS) and convert it into the XML files that dasblog expect. I could go with VBScript and MSXML, which I’m familiar with, and get it done in 30 minutes, or I could go with C# and the .net framework XML classes, which I’m not so familiar with, and get it done tonight, or I could install python, sit down with the newly released Dive into python 5.0 edition, and be stuck for the rest of the week. Decisions, decisions…

By the way, the templates that come with dasblog look nice, but they don’t work so good in Mozilla. More proof that Clemens Vasters hates open source 🙂