Saturday, June 9, 2012

Building HelloSun, Step 5: Clean Code is Happy Code

HelloSun: A guide to creating a social networking empire, from scratch, for free, circa 2012.
⇐ Step 4 T.O.C. Step 6 ⇒

So far the HelloSun code has been very sloppy, and sloppy code is bug-prone code. So today we won't add any new functionality, but will just clean up some areas of sloppiness. These are all small changes, but they'll make me feel better (I'm a bit anal-retentive that way).

use a lint tool

lint tools look for obvious problems in source code. I don't see any valid reason not to use them. I'm using JSLint, but there are alternatives.

This early in coding, JSLint recommended a few minor changes (all of which I accepted, in one case using jQuery's "each" call to avoid using "hasOwnProperty"), but found only one real bug: (the variable "i" was not declared in "chatty.jade", so would have overwritten any global "i" and would also have been inefficient).

At the top of all the JavaScript files are now lines similar to the following, which are hints to the JSLint tool I'm using.

  /*jslint white:false plusplus:false nomen:false */
  /*globals $, io */

I won't be submitting any more javascript code before running lint on it.

use a minimized version of jQuery

jQuery is nearly a standard in client-side Javascript now, and is used in the node-simple-chat example code we plagiarized in Step 4. To save a little download time I've changed to jQuery download in chatty.jade from




move server-side javascript into its own "chatty.js" file

"chatty.jade" contained a few dozen lines of javascript code embedded in the html file. I prefer to move this javascript code to its own "javascript/chatty.js" file because it 1) let's me run lint against the code, 2) treats the javascript as its own resource, and 3) is easier for me to read.

don't alter Array.prototype

The node-simple-chat example code we plagiarized in Step 4 used a trick of altering JavaScript's "Array.prototype" simply to add an "inject" method used once. I find it very bothersome to be altering a built-in Javascript object (can we be sure it's writable? can we be sure no other user of the Javascript global is not using a similar function, or is not iterating over an expected list?).

So I changed "Array.prototype.inject" in "chatserver.js" to a simple "inject_message" function.

prevent users from injecting malicious html code

This is the only serious problem we're fixing today.

Whenever you're allowing user-generated as your source for output, you're providing a big hole for malicious user to cause problems. In our chat program so far, we take whatever text the user enters for their name or their message, and display this text directly in the browser of all users.

Imagine that a user enters the message "I like <font color="green"><i>green italics</i><font>." This would immediately show up in every users window as:
myame: I like green italics.
You might think this innocent use of html codes is kind of cool. But if a user weren't so innocent, they might be inserting code to links, or uncouth images, or even malicious script that would be executed within every user's browser.
This would allow any user of your service to deliver malicious functionality to every other user of your service. Yikes!
A very simple solution is just to escape a few special characters ("<", ">", and "&") so that if they're part of user input that we are injecting into html, they will not be seen as raw html characters. This is done with the "simple_html_escape" function added to chatty.js:

  function simple_html_escape(s)
      return s.replace(/&/g,'&')

"simple_html_escape()" is then added to "function appendMsg()" wherever the user-generated strings are display in the output page.

Getting the code

Today's code is labeled v0001.0004 and is available in these formats:
HelloSun: A guide to creating a social networking empire, from scratch, for free, circa 2012.
⇐ Step 4 T.O.C. Step 6 ⇒

No comments:

Post a Comment