Wednesday, October 25, 2006

How to Check Your Website with Multiple Browsers on a Single Machine (Cross-Browser Compatibility Checking)

How to Check Your Website with Multiple Browsers on a Single Machine (Cross-Browser Compatibility Checking)
by Christopher Heng, thesitewizard.com

We all know the importance of checking our web pages with multiple browsers, especially when we are designing a new layout for a website. The number of extant browsers we need to check with are enormous: Internet Explorer (IE) 6, IE 5.5, IE 5.0, Netscape 7.X (ie, Mozilla 1.0.X), Netscape 6.X (or Mozilla 0.9.X), Mozilla 1.3.X (and above), Opera 7, Opera 6/5, Netscape 4.X, IE 4.X and so on. And then there are the different platforms: Windows, Macintosh (Mac), Linux, etc. The problem for most people is that multiple versions of certain browsers cannot co-exist with each other, the most notable example of this is IE for Windows. Unless you are privileged to have multiple computers, this presents a certain difficulty for the average webmaster. This article suggests some ways for you to run multiple versions of multiple browsers on one computer.
Note that this article is written primarily from the point of view of a person using Windows (the majority of people reading this article), although it does address the issue of Mac browsers and Linux browsers as well.
Mozilla and Netscape
It's possible for Netscape 4.X, Netscape 6.X (or Mozilla 0.9.X), Netscape 7 (Mozilla 1.0.X), Mozilla 1.1.X, Mozilla 1.2.X, Mozilla 1.3.X (and so on) to all co-exist on the same machine.
1. Netscape 4.X
You should have one version of the Netscape 4.X series installed. Take your pick - they are all approximately the same in their level of support for the Cascading Style Sheets (CSS) standards. Some people prefer to use one of the older versions on the basis that if their page renders correctly on that version, it should theoretically render correctly on the later 4.X versions. My approach is to simply install the latest in this series: I suspect that fixes made in the later versions are mainly security fixes. In any case, my testing with this browser is restricted to making sure that people using the browser can read and navigate thesitewizard.com and thefreecountry.com with the browser. I don't spend any time at all making the site look good for the browser, since the number of people using this browser is decreasing all the time. (It's the law of diminishing returns.)
Netscape makes older versions of its browsers available from http://wp.netscape.com/download/archive.html
2. Netscape 6.X, Netscape 7.X, Mozilla 1.X
If you did not already know, Netscape 6/7 (and later) and Mozilla use the same Gecko rendering engine. As such, if you have Netscape 6.X, you are in effect using the rendering engine of a beta version of Mozilla (one of the 0.9.X series); if you use Netscape 7, you are using the Mozilla 1.0.X engine; and if you use Netscape 7.1 you're using the same engine as Mozilla 1.4. The point is that you don't have to install, say, Mozilla 1.0.X if you're using Netscape 7, and so on. My personal preference is to have one of each of the major releases of Netscape installed (or their Mozilla equivalent), as well as the latest released version of Mozilla. At the time I write this, this works out to be Netscape 6.X, Netscape 7 and Mozilla 1.4 (same as Netscape 7.1).
It is easy to make these versions of Netscape/Mozilla co-exist with each other. Install them into separate directories and create a different profile for each browser you install. (For non-Netscape/Mozilla users, this browser allows you to create different profiles so that you can store different settings for different situations.) To create a different profile, simply start up the Mozilla or Netscape Profile Manager, and answer the questions given by the wizard. Be sure you do this before you start configuring each browser, or the settings you make in one browser may bleed over to the other, and possibly confuse the other version.
Once you've finished creating profiles, you will want to create shortcuts (Windows terminology) to run the different versions of the browser. This makes life easier for you: you can simply click the appropriate icon for the different versions, and it will load using the correct profile. To specify which profile the browser is to load, put the profile name after the "-P" option.
For example, if you have created a profile named "netscape6", your command for running (say) Netscape with that profile may look like:

"C:\Program Files\Netscape\Netscape 6\netscp6.exe" -P netscape6

Similarly, your command to run Mozilla 1.4 with a profile called "mozilla" may look like:

"C:\Program Files\mozilla.org\Mozilla\mozilla.exe" -P mozilla

And so on.
The latest version of Netscape can be obtained from http://channels.netscape.com/ns/browsers/download.jsp
Mozilla can be obtained from http://www.mozilla.org
Opera for Windows/Linux
Opera is the third most used browser used on thesitewizard.com and thefreecountry.com, and is particularly popular among the seasoned webmaster community (which probably explains why so many of my visitors use it).
Opera 6 and 7 can co-exist on one computer. If you want to install both versions on Windows, simply put them in separate directories. No extra steps are required. I don't know if this also works with earlier versions of Opera, since I don't bother to check my site with those.
As for Linux, at the time I write this, I only have version 6 of Opera installed, so I have no idea if two versions can co-exist on that platform.
You can obtain Opera for any of its supported operating systems from Opera's website. To get older versions, just navigate to the downloads page and click the "Opera archives" link.
Internet Explorer 5.0, 5.5, 6.0 for Windows
In all my sites, at the time of this writing, IE users comprise the majority of visitors, with the bulk of them using IE 6.0.
My experience in coding the recent new designs for thesitewizard.com and thefreecountry.com, both of which depend heavily upon Cascading Style Sheets for layout, is that IE 6 is a very different animal from IE 5.X. Contrary to what you may expect, what works in IE 5.5 does not necessarily work in IE 6. In fact, if my limited experience with coding my sites is anything to go by, what works for IE 6 is more likely to work for IE 5.5 than vice versa. As a result, if you can only install one version of IE, and your site uses CSS, a case can be made that it is better to install IE 6 than 5.X.
(It seems that IE 6 has a number of bugs in its CSS box model, causing sites that work in Mozilla/Netscape, Opera and IE 5.X to break under IE 6. That is not to say that IE 5 does not have bugs. All the more reason to install multiple versions.)
Unlike Opera, Mozilla and Netscape, you can only install one version of IE in a single installation of Windows. The bulk of IE's code does not get installed into its own subdirectory (or folder) but into Windows' system directory, so even if you somehow successfully install different versions of IE, they will all wind up using the code for the latest installed version (assuming they don't crash).
1. Running Two or Three Versions of IE on One Machine
The simplest way to run two versions of IE on a single machine is to install two versions of Windows in that machine. That is, install Windows 95/98/ME (ie, either Windows 95 or 98 or 98 Second Edition or ME) onto one partition on your hard drive, and install Windows 2000 or XP in another partition in a dual-boot configuration.
In plain English, this means that you need to partition your hard disk into (at least) two partitions. First install Windows 95/98/98SE/ME into drive C:. When you finish that, run the Windows 2000 or Windows XP setup program from within the first version of Windows you installed. Select the "Clean install" option and not the "Upgrade" option when you're asked. You will be presented with a window later where you can click the "Advanced options" button. In the window that is displayed, check the box labelled "I want to choose the installation partition during setup". Later in the installation process, when you are asked, choose to install Windows 2000 (or XP) in the second partition. Windows 2000 or XP will then (automatically) install a menu that appears when you start up your machine, allowing you to choose the version of Windows you want to boot.
It is apparently also possible to install three versions of Windows (and hence three versions of IE) into one machine without resorting to third party software. You'll need to have at least three partitions on your hard disk to play with. Install Windows 95/98/98SE/ME into C: and use the above procedure to install Windows 2000 into the second partition. Finally, use the same procedure to install Windows XP into the third partition. I have not tried "triple booting" three Windows versions before, but one of thesitewizard.com's visitors has assured me that it works. With three versions of Windows to play with, you should be able to use three versions of IE on the same machine.
Note that Windows 95 installs IE 3 by default, Windows 98 installs IE 4, Windows 98 Second Edition installs IE 5.0, Windows 2000 installs IE 5.0, Windows ME installs IE 5.5 and Windows XP installs IE 6.0, so if you might want to plan carefully which Windows version you install so that you get the IE version you need for testing. As far as I know, you can't easily (if at all) "downgrade" a version of IE (although you can upgrade it), so if you need something as old as IE 4, you might need to install Windows 98 (or even Windows 95 and upgrade IE to 4.0).
2. Running More than Three Versions of Internet Explorer
If you really need to run more than three versions of IE and can't afford to (or don't want to) use another machine, you'll need to install either an emulator or use one of those software that creates a virtual machine (sometimes called a virtualizer).
Loosely speaking, an emulator allows you to run another copy of Windows within your existing version of Windows or Linux (or FreeBSD or whatever). The emulator pretends to be a new computer, and Windows gets installed into a small space on your hard disk which the emulator uses to mimic an entire drive.
You can find a list of free PC emulators and virtualizers listed on thefreecountry.com's Free PC (x86) Emulators and Virtual Machines at http://www.thefreecountry.com/emulators/pc.shtml
Some of the emulators listed there, such as Bochs, allow you to emulate a PC machine on which you can install Windows or Linux or any other PC operating system. Bochs itself may be installed on Windows, Linux, Mac, and possibly other systems and machines as well. If you are a Mac user, this is one way to run the Windows version of IE without having to buy a PC.
Be warned though that full emulators like Bochs are extremely slow. You may be able to tolerate it though, if you are only using it to test your web pages once in a blue moon.
If you already have a PC, another solution is to run a program that can create virtual machines. While emulators can pretend to be a completely different machine (such as a Mac pretending to be a PC), virtual machines merely sets up a space within your existing machine and runs a new copy of the operating system (such as Windows) within that space. The new copy of (say) Windows thinks that it is the only one running (even if you are running it within (say) yet another copy of Windows. Since virtual machines do not have to emulate a completely different machine, they tend to be slightly faster than full emulators.
Free virtual machines can be found on the same page as the emulators on Free PC (x86) Emulators and Virtualizers at http://www.thefreecountry.com/emulators/pc.shtml
Once you have obtained an emulator or a virtualizer, you simply install a new copy of Windows in each "machine" you set up. For each copy of Windows you set up, install a different version of IE, and you're done.
Testing Mac Browsers
As you might expect, the easiest way to test your page on Mac browsers (like Safari, Camino, Mozilla, Opera, etc) is to actually own a Mac.
However, work is under way in the open source software community to create a PowerPC Mac emulator for x86 machines (ie, PCs) that will run Mac OS X. Once this project is complete, you should be able to simply download the emulator, buy a copy of Mac OS X, install them on your PC, and you have a working Macintosh in a window of your Linux or Windows machine that you can use to test your site under Mac browsers. Don't expect your emulated Macintosh to perform at the same speed as a real Mac though. For the purpose of occasionally testing a website or two, though, the emulator will probably suffice if you have a healthy dose of patience.
You can also run Mac emulators for the older 68k Macs (like Quadra, Performa, etc). These emulators, however, require you to have a real Mac around, since you need to copy the ROM from one of those Macs before the emulator will work. In any case, for the purpose of testing web pages, the 68k Macintosh emulators are not very useful, since they can only emulate the older Macs, which only run browsers like IE 4 and Netscape 4. If your site is like mine, you will find that people using such browsers are few and far between (if at all).
Anyway, if you're curious, you can find free Mac emulators listed on thefreecountry.com's Free 68k and PowerPC Macintosh Emulators at http://www.thefreecountry.com/emulators/macintosh.shtml
Testing Linux Browsers
One of the easiest ways to test your site to see how it appears under Linux is to run Linux from a CDROM. There are numerous Linux "live" CDROMs around. These allow you to simply boot your machine from the CDROM directly into Linux without having to install anything onto your hard disk. One of the best-known "live" Linux systems around is Knoppix, which you can obtain from http://www.knopper.net/knoppix/index-en.html. Essentially, all you have to do is to download the ISO (which is just an image of the CDROM), burn it to your CDR, put it in your CDROM drive, and restart your computer. Knoppix is free.
Alternatively, if you prefer to install Linux on your hard disk, it can be set up so that it co-exists with Windows. Make sure you have space for a new partition on your hard disk, install it and you're done.
The default browser that comes on many Linux distributions is Mozilla. However, you will find that even though Mozilla basically renders your page identically for all platforms, the fonts available under Linux are different from those available on Windows. If you don't code your font tags or CSS font-families in a cross-platform compatible way, your site may wind up being rendered with an ugly font. For example, many sites simply specify "Arial" or "Impact" or some such Windows font for their site. Since these fonts are not available by default under non-Windows systems, your site will be rendered using either the default font on those browsers or some other font that the browser thinks matches the type of font you've specified. If you don't want to bother to run Linux to test, be sure that you at least:
Test your pages under Mozilla for your platform.
Specify generally available alternative fonts for your web pages. For example, don't just say,

font-family: Arial ;

in your style sheet, say

font-family: Arial, Helvetica, sans-serif ;

instead.
There are a number of other browsers available on the Linux platform. You may have seen them in your web logs. They include, for example, Konqueror, Opera for Linux and Mozilla spin-offs.
Conclusion
It's a good idea to test your site with multiple versions of multiple browsers, particularly if you plan to do anything fancy with style sheets on your site. This doesn't mean that you have to support all browsers - for example, the pages on thesitewizard.com do not work well (if at all) under IE 4 and Netscape 3 (and earlier). However, when you are able to test your pages this way, you can at least reduce the number of problems your pages have with the different browsers. The tips in this article allow you to test with multiple browsers even if you have only one machine.
Copyright 2003-2004 by Christopher Heng. All rights reserved.Get more free tips and articles like this, on web design, promotion, revenue and scripting, from http://www.thesitewizard.com/.
This article can be found at http://www.thesitewizard.com/webdesign/multiplebrowsers.shtml
thesitewizard™ RSS Site Feed
Do you find this article useful? You can learn of new articles and scripts that are published on thesitewizard.com by subscribing to the RSS feed. Simply point your RSS feed reader or a browser that supports RSS feeds at http://www.thesitewizard.com/thesitewizard.xml. You can read more about how to subscribe to RSS site feeds from our RSS FAQ.
Please Do Not Reprint This Article
This article is copyrighted. Please do not reproduce this article in whole or part, in any form, without obtaining my written permission.
Related Pages
Appearance, Usability and Search Engine Visibility in Web DesignHTML and CSS Validation: Should You Validate Your Web Page?Designing for Browser and Platform CompatibilityDisabling the Image Toolbar in IE 6 for Your WebsiteIs Your Site Ready for the Average User?Two Common Web Design MythsWhich Web Host Would You Recommend? (FAQ)How to Register Your Own Domain NameFree HTML Editors and WYSIWYG Web EditorsFree FTP Clients
New Articles / Pages
Frequently Asked Questions (FAQ) about the Feedback Form WizardNvu Tutorial 5: How to Add a Feedback Form to Your WebsiteHow to Upload a File to Your Website Using the FileZilla FTP ClientNvu Tutorial 4: How to Create a Multiple Column LayoutNvu Tutorial 1: How to Design and Publish Your Website with Nvu (free WYSIWYG web editor)Appearance, Usability and Search Engine Visibility in Web DesignHTML and CSS Validation: Should You Validate Your Web Page?How to Check Your Website with Multiple Browsers on a Single Machine (Cross-Browser Compatibility Checking)Your Website's Spelling and the Search EnginesWhich Web Host Would You Recommend? (FAQ)
How to Link to This Page
To link to this page from your website, simply cut and paste the following code to your web page.
How to Check Your Website with Multiple Browsers on a Single Machine (Cross-Browser Compatibility Checking)

It will appear on your page as

Java Book Reviews

This is the place to find Java book reviews covering all aspects of Java programming, from introductions to specialised topics to J2EE to primers on object oriented development. Also covered are topics dear to the hearts of Java developers, including books on development tools such as Eclipse, XML and web services from a Java perspective to general programming topics and software methodologies.
If you don't find what you're looking for then take a look also at the TechBookReport programming book reviews, the XML book reviews, the web book reviews or software methodologies.



Ant: The Definitive Guide by Steve Holzner
Apache Derby - Off To The Races by Zikopoulous, Scott and Baklarz
Apache Jakarta Commons: Reusable Java Components by Will Iverson
Applied Evolutionary Algorithms in Java by Robert Ghanea-Hercock
Beginning Java 2 (JDK 1.4 Edition) by Ivor Horton
Better, Faster, Lighter Java by Bruce Tate and Justin Gehtland
Beyond Java by Bruce Tate
Code Complete by Steve McConnell
Code Quality by Diomidis Spinellis
Code Reading by Diomidis Spinellis
Cryptography In The Database by Kevin Kenan
Data Crunching by Greg Wilson
Data Structures With Java by John R. Hubbard and Anita Huray
Design Patterns Explained by A. Shalloway and J. Trott
Eclipse - Building Commercial-Quality Plugins by Eric Clayberg and Dan Rubel
Eclipse 3 Live by Bill Dudney
Eclipse 3.0 Kick Start by Carlos Valcarcel
Eclipse by Steve Holzner
Eclipse Cookbook by Steve Holzner
Effective Java by Joshua Bloch
The Elements of Java Style
Embedded Ethernet and Internet Complete by Jan Axelson
FindBugs
From Java To C# - A Developer's Guide by Heng Ngee Mok
Google Hacks by Tara Calishain and Rael Dornfest
Google Hacks, 2 by Tara Calishain and Rael Dornfest
Google, Amazon, and Beyond by Tom Myers and Alexander Nakhimovsky
Guide to J2EE: Enterprise Java by John Hunt and Chris Loftus
Hardcore Java by Robert Simmons, Jr
Head First Design Patterns by Eric and Elisabeth Freeman
Head First Java by Kathy Sierra and Bert Bates
Head First Java, 2e by Kathy Sierra and Bert Bates
Holub On Patterns by Allen Holub
IBM Rational ClearCase, Ant and CruiseControl by Kevin Lee
Integrated Solutions With DB2 by Rob Cutlip and John Medicke
Java 6 Platform Revealed by John Zukowski
Java Application Development On Linux by Carl Albing and Michael Schwarz
Java Concurrency In Practice by Brian Goetz
Java Cookbook by Ian Darwin
Java Data Objects by David Jordan and Craig Russell
Java Developers Almanac 1.4 by Patrick Chan
Java EE and .NET Interoperability by Marina Fisher, Ray Lai, Sonu Sharma and Laurence Moroney
Java Examples In A Nutshell by David Flanagan
Java Garage by Eben Hewitt
Java How To Program (5e) by Deitel and Deitel
Java I/O by Elliotte Rusty Hardold
Java In A Nutshell by David Flanagan
Java Puzzlers by Joshua Bloch and Neal gafter
Java Regular Expressions by Mehran Habibi
JCreator 3.5
JCreator Pro 2.5
JDiskReport 1.2
jEdit 4.2
Just Java 2 by Peter Van Der Linden
Learning Jakarta Stuts 1.2 by Stephan Wiesner
Learning Java, 3e by Patrick Niemeyer and Jonathan Knudsen
Learning UML 2.0 by Russ Miles and Kim Hamilton
Murach's Java Servlets and JSP by Andrea Steelman and Joel Murach
NetBeans IDE Field Guide by Patrick Keegan et al
NetBeans IDE Field Guide, 2e by Patrick Keegan et al
The No Fluff Just Stuff 2006 Anthology by Neal Ford
The Object-Oriented Thought Process by Matt Weisfeld
Objects First With Java by David J Barnes and Michael Kolling
POJOs In Action by Chris Richardson
Processing XML with Java by Elliotte Rusty Harold
Quartz Job Scheduling Framework by Chuck Cavaness
Refactoring: Improving the Design of Existing Code by Martin Fowler et al
Regular Expression Pocket Reference by Tony Stubblebine
RSSOwl 1.1.3
Spring: A Developer's Notebook by Bruce Tate and Justin Gehtland
SQuirreL SQL Client v1.1
Swing Hacks by Joshua Marinacci and Chris Adamson
Teach Yourself J2EE In 21 Days by Bond, Law et al
Teach Yourself Java 2 In 24 Hours by Rogers Cadenhead
Technical Java by Grant Palmer
Test-Driven Devlopment: A J2EE Example by Thomas Hammell
Thinking In Java (4e) by Bruce Eckel
Thinking In Java by Bruce Eckel
Wicked Cool Java by Brian D. Eubanks
XML Hacks by Michael Fitzgerald
XML Primer Plus by Nicholas Chase
XSLT Cookbook by Sal Mangano

Tuesday, October 17, 2006

Brian Slesinsky's Weblog

Wrap Strings in Classes to Increase Security

Forgetting to validate user input is an increasingly common security hole in web applications. Here's an elegant way to fix a hole and make your code more understandable at the same time.
Code that reads HTTP request parameters often looks something like this:

String productId = request.getParameter("id");
doSomething(productId);

The problem here is that we haven't validated the id parameter, and this string came from the network, so it could contain just about anything. The security holes caused by this can be somewhat surprising. For example, suppose we go on to do a redirect:

response.sendRedirect("https://www.example.com/page2?id=" + productId);

See the bug yet?
Suppose id starts with a newline, such as "\nsomething". The full HTTP response will look something like this:
HTTP/1.x 302 Found
Location: http://www.example.com/page2?id=
something

The attacker can put anything they like into the HTTP response, or even add multiple HTTP responses. (This is known as HTTP response splitting.)
It's relatively easy to spot the problem in a simple example like this because there's so little code. The solution is also easy to state: always validate any string that comes from the network.
However, there are often many method calls between the code that reads the request and the code that prints the response. Maybe we've crossed several layers as well. As the months go by and the code gets changed by multiple developers, it's easy to forget which methods have responsibility for doing input checking and drop the ball. It's very easy to assume that a variable named "productId" actually contains something that at least looks like a productId, but that only works if every request handler did its job.
Software developers have come up with many ways to fix this problem. Some of them are pretty cumbersome, like writing warnings everywhere saying who has responsibility for what, or using Hungarian notation. Some languages (such as Perl and Ruby) use taint-checking to report a runtime error when the program attempts to use untrusted input.
In Java, the approach I prefer is to introduce a new class:

public class ProductId {
private static final Pattern regexp = ...

private final String id;

ProductId(String allegedId) {
if (!regexp.matcher(allegedId).matches()) {
throw new IllegalArgumentException("invalid id: "+allegedId);
}
this.id = allegedId;
}

public String toString() {
return id;
}

...
}


At first glance this class doesn't seem to do very much. Wouldn't a checkProductId() method be sufficient?
The beauty of introducing a class is that it gives verified product id's a type. Any API that doesn't verify input itself can take arguments of type ProductId and be confident that the caller will do the checking, because the only way to get a ProductId type is to call the constructor:

ProductId productId = new ProductId(request.getParameter("id"));
doSomething(productId);


In an application written this way, the convention is that bare Strings are unverified and domain-specific types are verified (at least so far as syntax is concerned). This convention is enforced by the type-checker. When J. Random Coder comes along and writes yet another HTTP request handler, he or she will find that every relevant API takes a ProductId, and will probably complain about the silly programmers who wrote this API and went totally overboard with their do-nothing classes when a simple String would work fine, not even realizing that calling this silly constructor adds a security check.
Comments, code review, or unit testing can't give you the same guarantee because they all assume diligence on the part of the programmer. (Not that there's anything wrong with diligence, but there is a limited supply that we'd rather spend in other ways.) Taint-checking would do it (assuming reasonable test coverage) but we don't have that in Java. What we do have is a pretty good type system, so we might as well get it to do some work for us.
As an added bonus, when you introduce specific types for things, your code gets easier to read. For one thing, naming variables or methods "productId" becomes silly, because then you have:

// Do you think this code uses a product id?
ProductId productId = foo.getProductId();


Now that we have a type for it, we don't have to keep repeating to ourselves that this String is a product id, and so is this String, and this other method returns a String that is also a product id, and the third String argument in this method call is a product id, and so on and so forth. Those sort of naming schemes are for languages with weak type systems, not Java. We can use names for higher-level concepts:

ProductId itemToDisplay = foo.getSelection();

And if that's not enough reason to do it, your favorite IDE will become smarter. When it does method completion on a product id, no longer will it give you irrelevant String methods like toLowerCase() or replaceFirst(), things that nobody should want to do with a product id anyway. (Or if they really want to, they can call toString() first.) Now it will give you intelligent suggestions like getShard() or isISBN(), because ProductId becomes the logical place to put these methods instead of hiding them in some utility class somewhere. And when you get usages on a product id, the IDE will no longer show you every place a String is used (which is everywhere, which is a useless search result). Instead you'll see code that actually has something to do with product id's.