A pedant that hangs out in the dark corner-cases of the web.

Monday, December 04, 2006

jar help is misleading

Java developers, type jar and you are shown:

Usage: jar {ctxu}[vfm0Mi] [jar-file] [manifest-file] [-C dir] files ...

The problem? The name of the jar-file and the manifest-file must appear in the same order as the f and m options (respectively), or it will fail.

Thursday, November 30, 2006

MS LogParser Recipe: Local Time and Human-Readable Browser + OS

select to_localtime(to_timestamp(date,time)) as when,
coalesce(s-computername,computer_name()) as server,
extract_filename(LogFilename) as logfile, LogRow as line,
coalesce(c-ip,'') as ipaddr, coalesce(replace_chr(cs(User-Agent),'+',' '),'') as useragent,
coalesce(cs-uri-stem,'') as path, coalesce(cs-uri-query,'') as query,
coalesce(cs(Referer),'') as referrer,
case strcnt(cs(User-Agent),'LWP::Simple/') when 1 then strcat('Perl script ',extract_prefix(extract_suffix(cs(User-Agent),0,'LWP::Simple/'),0,'+'))
else case strcnt(cs(User-Agent),'PSP+(PlayStation+Portable);+') when 1 then strcat('PlayStation Portable ',extract_prefix(extract_suffix(cs(User-Agent),0,'PSP+(PlayStation+Portable);+'),0,')'))
else case strcnt(cs(User-Agent),'WebTV/') when 1 then strcat('WebTV ',extract_prefix(extract_suffix(cs(User-Agent),0,'WebTV/'),0,'+'))
else case strcnt(cs(User-Agent),'BlackBerry') when 1 then strcat('BlackBerry ',extract_prefix(extract_suffix(cs(User-Agent),0,'BlackBerry'),0,'+'))
else case strcnt(cs(User-Agent),'Danger+hiptop+') when 1 then strcat('Danger hiptop ',extract_prefix(extract_suffix(cs(User-Agent),0,'Danger+hiptop+'),0,';'))
else case strcnt(cs(User-Agent),'UP.Browser/') when 1 then strcat('UP.Browser ',extract_prefix(extract_suffix(cs(User-Agent),0,'UP.Browser/'),0,'+'))
else case strcnt(cs(User-Agent),'Picsel-ePAGE-Browser/') when 1 then strcat('Picsel ePAGE ',extract_prefix(extract_suffix(cs(User-Agent),0,'Picsel-ePAGE-Browser/'),0,'+'))
else
strcat(strcat(strcat(strcat(strcat( strcat(strcat(
-- browser name
case strcnt(cs(User-Agent),'Opera+') when 1 then strcat('Opera ',extract_prefix(extract_suffix(cs(User-Agent),0,'Opera+'),0,'+'))
else case strcnt(cs(User-Agent),'Opera/') when 1 then strcat('Opera ',extract_prefix(extract_suffix(cs(User-Agent),0,'Opera/'),0,'+'))
else case strcnt(cs(User-Agent),'iCab+') when 1 then strcat('iCab ',extract_prefix(extract_suffix(cs(User-Agent),0,'iCab+'),0,'+'))
else case strcnt(cs(User-Agent),'iCab/') when 1 then strcat('iCab ',extract_prefix(extract_suffix(cs(User-Agent),0,'iCab/'),0,'+'))
else case strcnt(cs(User-Agent),'Netscape/') when 1 then strcat('Netscape ',extract_prefix(extract_suffix(cs(User-Agent),0,'Netscape/'),0,'+'))
else case strcnt(cs(User-Agent),'Netscape6/') when 1 then strcat('Netscape ',extract_prefix(extract_suffix(cs(User-Agent),0,'Netscape6/'),0,'+'))
else case strcnt(cs(User-Agent),'MSIE+') when 1 then strcat('MSIE ',extract_prefix(extract_suffix(cs(User-Agent),0,'MSIE+'),0,';'))
else case strcnt(cs(User-Agent),'Firefox/') when 1 then strcat('Firefox ',extract_prefix(extract_suffix(cs(User-Agent),0,'Firefox/'),0,'+'))
else case strcnt(cs(User-Agent),'Safari/') when 1 then strcat('Safari ',extract_prefix(extract_suffix(cs(User-Agent),0,'Safari/'),0,'+'))
else case strcnt(cs(User-Agent),'Flock/') when 1 then strcat('Flock ',extract_prefix(extract_suffix(cs(User-Agent),0,'Flock/'),0,'+'))
else case strcnt(cs(User-Agent),'OmniWeb/v') when 1 then strcat('OmniWeb ',extract_prefix(extract_suffix(cs(User-Agent),0,'OmniWeb/v'),0,'+'))
else case strcnt(cs(User-Agent),'Konqueror/') when 1 then strcat('Konqueror ',extract_prefix(extract_suffix(cs(User-Agent),0,'Konqueror/'),0,'+'))
else case strcnt(cs(User-Agent),'K-Meleon/') when 1 then strcat('K-Meleon ',extract_prefix(extract_suffix(cs(User-Agent),0,'K-Meleon/'),0,'+'))
else case strcnt(cs(User-Agent),'Camino/') when 1 then strcat('Camino ',extract_prefix(extract_suffix(cs(User-Agent),0,'Camino/'),0,'+'))
else case strcnt(cs(User-Agent),'Galeon/') when 1 then strcat('Galeon ',extract_prefix(extract_suffix(cs(User-Agent),0,'Galeon/'),0,'+'))
else case strcnt(cs(User-Agent),'Epiphany/') when 1 then strcat('Epiphany ',extract_prefix(extract_suffix(cs(User-Agent),0,'Epiphany/'),0,'+'))
else case strcnt(cs(User-Agent),'Firebird/') when 1 then strcat('Firebird ',extract_prefix(extract_suffix(cs(User-Agent),0,'Firebird/'),0,'+'))
else case strcnt(cs(User-Agent),'Phoenix/') when 1 then strcat('Phoenix ',extract_prefix(extract_suffix(cs(User-Agent),0,'Phoenix/'),0,'+'))
else case strcnt(cs(User-Agent),'Links+(') when 1 then strcat('Links ',extract_prefix(extract_suffix(cs(User-Agent),0,'Links+('),0,';'))
else case strcnt(cs(User-Agent),'+rv:') when 1 then strcat('Mozilla ',extract_prefix(extract_suffix(cs(User-Agent),0,'+rv:'),0,')'))
end end end end end end end end end end end end end end end end end end end end,
-- operating system
strcat(case strcnt(cs(User-Agent),'Windows+') when 1 then
case strcnt(cs(User-Agent),'Windows+NT+6.0') when 1 then ' Windows Vista'
else case strcnt(cs(User-Agent),'Windows+NT+5.2') when 1 then ' Windows 2003'
else case strcnt(cs(User-Agent),'Windows+NT+5.1') when 1 then ' Windows XP'
else case strcnt(cs(User-Agent),'Windows+NT+5.0') when 1 then ' Windows 2000'
else case strcnt(cs(User-Agent),'Windows+NT+') when 1 then strcat(' Windows ',extract_prefix(extract_suffix(cs(User-Agent),0,'Windows+NT+'),0,';'))
else strcat(' Windows ',extract_prefix(extract_prefix(extract_suffix(cs(User-Agent),0,'Windows+'),0,';'),0,')'))
end end end end end
else case strcnt(cs(User-Agent),'Win98') when 1 then ' Windows 98'
else case strcnt(cs(User-Agent),'Win95') when 1 then ' Windows 95'
else case strcnt(cs(User-Agent),'Win+9x+4.90') when 1 then ' Windows ME'
else case strcnt(cs(User-Agent),'WinNT4.0') when 1 then ' Windows NT 4'
else case strcnt(cs(User-Agent),'OS+X') when 1 then ' Mac OS X'
else case strcnt(cs(User-Agent),'Mac') when 1 then
case strcnt(cs(User-Agent),'PPC') when 1 then ' Mac PPC'
else case strcnt(cs(User-Agent),'PowerPC') when 1 then ' Mac PPC'
else ' Mac'
end end
else case strcnt(cs(User-Agent),'Linux') when 1 then ' Linux'
else case strcnt(cs(User-Agent),'FreeBSD') when 1 then ' FreeBSD'
end end end end end end end end end,
case strcnt(cs(User-Agent),'Media+Center+PC+') when 1 then strcat(' Media Center ',extract_prefix(extract_prefix(extract_suffix(cs(User-Agent),0,'Media+Center+PC+'),0,';'),0,')')) end)),
-- major ISPs
case strcnt(cs(User-Agent),'AOL/') when 1 then strcat(' AOL ',extract_prefix(extract_suffix(cs(User-Agent),0,'AOL/'),0,'+'))
else case strcnt(cs(User-Agent),'CS+2000+') when 1 then strcat(' CompuServe 2000 ',extract_prefix(extract_suffix(cs(User-Agent),0,'CS+2000+'),0,'/'))
end end),
-- spyware
case strcnt(cs(User-Agent),'FunWebProducts') when 0 then '' else ' FunWebProducts (spyware)' end),
case strcnt(cs(User-Agent),'Hotbar') when 1 then ' Hotbar (spyware)' end),
case strcnt(cs(User-Agent),'iebar') when 1 then ' IEBar (spyware)' end),
case strcnt(cs(User-Agent),'sureseeker.com') when 1 then ' sureseeker (spyware)' end),
case strcnt(cs(User-Agent),'FrankenShteiN') when 1 then ' Win32.Mydoom.W (virus)' end)
end end end end end end end as browser

Friday, November 24, 2006

Edit != Execute

The publisher could not be verified.  Are you sure you want to run this software?<br />Name: sync.cmd<br />Publisher: Unknown Publisher<br />Type: Windows Command Script<br />From: M:\<br />Run  Save  Cancel<br />Al&ways ask before opening this file<br />This file does not have a valid digital signature that verifies its publisher.  You should only run software from publishers you trust.  [How can I decide what software to run?]

Here's a major Windows security screw-up that's actually been around for a while: if you try to edit a script or batch file that Windows has decided is "unsigned" via the context menu, you are asked if you are sure you want to run it, since the publisher cannot be verified. If you choose "Run" (since you don't want to "Cancel"), Windows executes the file!

Wednesday, November 22, 2006

Client-side include recipe

<!--[if IE]>
<object classid="clsid:25336920-03F9-11CF-8FD0-00AA00686F13" data="some.html">
<p>backup content</p>
</object>
<![endif]-->

<!--[if !IE]> <-->
<object type="text/html" data="some.html">
<p>backup content</p>
</object>
<!--> <![endif]-->

The included body, for IE, must also specify border:0;overflow:visible.

Insert HTML page into another HTML page | published @ aplus moments

Saturday, November 18, 2006

Firefox extension: Uppity

For those of you who miss the old diggler Mozilla extension, Lifehacker promulgates the Uppity Firefox extension. It eases the process of walking up a site's directory tree.

Wednesday, November 15, 2006

IE7 and Firefox2: What's New?

Microsoft has finally, after five years, released an upgrade to Internet Explorer. Within days, Mozilla released version 2 of the popular Firefox web browser. So, what's new?

Internet Explorer 7Firefox 2
  • IE7 has tabs, Firefox2 has improved tabs

    IE7 adds tabbed browsing, which allows you to open links in a new tab, without leaving the page you are on. This is especially useful when searching or shopping.

    Firefox2 has added a close button to each tab, a list of recently closed tabs to the History menu, and the list of tabs now scrolls when there are too many to show.

  • IE7 has feeds, Firefox2 has enhanced feeds

    RSS feed in IE7IE7 now understands RSS, Atom, and other feed sources, to stay up-to-date with news, classified ads, and more.

    IE7 RSS feed iconRSS feeds in IE7

    RSS feed in Firefox2Firefox2 has added support for viewing feeds and adding them to your favorite feed reader.

    An RSS feed as a Firefox live bookmark
  • IE7 has a search box, Firefox2 has an improved search box
    IE7 search box

    IE7 has added a search box that allows you to search the web more efficiently, using many different sites.

    Firefox2 has integrated Google Suggest into its search box.

    Google suggest in Firefox2Google Suggest in Firefox2 as a calculator
  • IE7 and Firefox2 have both added a phishing filter

    Both browsers now alert you to forged websites.

    IE7 anti-phishing messageFirefox2 anti-phishing message
  • IE7 can shink a printout to fit a single page
    IE7 print preview
  • Firefox2 spell-checks your forms

    Firefox2 spell-checking
  • IE7 has improved security

    IE7 has made significant security gains to address persistant problems it has dealt with in previous versions, including the aforementioned phishing filter, safer web address interpretation, better control over ActiveX and add-ons, and pop-up windows now include an accurate address. IE7 also runs in protected mode, to ensure it can't do anything bad, but only on Windows Vista.

  • IE7 handles web technologies far better now

    International web addresses, and some advanced styles now work in IE, and many display problems in IE6 have been fixed.

  • Firefox2 can remember your session

    Persistent sessions in Firefox2Firefox2 automatically restores your windows and tabs, history, in-progress downloads, and anything you typed into forms after a crash, upgrade, or whenever you start (if you've asked for it).

Conclusion: IE7 is largely playing catch-up for the time Microsoft left the product fallow, but Firefox isn't waiting around for it to catch-up.

Consensus: Firefox2 vs. IE7

So, which is better? It's nearly unanimous.

Monday, October 23, 2006

Dear Adobe,

Opening PDFs inside the browser is clearly too hard for you to do reliably, so it's time to turn off the default setting for "Display PDF in browser".

IE7 and Firefox2 released

IE7

Firefox2

Recommendation: Firefox. First, IE has made excellent progress, but after five years of stagnation it still comes off as "Firefox Lite". Second, too many people still use MSIE than is healthy for the Internet; monoculture (any system that has very low diversity) is dangerous from a security perspective. Hopefully we will eventually see an even split between IE, Firefox, Safari, and Opera.

Excellent WebForms 2.0 Demo Site

Web Forms 2

Saturday, August 26, 2006

Firefox: Using nsIWebProgressListener

Searching for many hours for an example of how to create and register an object that implements nsIWebProgressListener, I finally found this comment buried in an unrelated post that unlocked everything for me:

Are you looking for nsIWebProgressListener?

top.getBrowser().addProgressListener(...a listener object);

A minimal object:


var progressListener = {
stateIsRequest:false,
QueryInterface : function(aIID) {
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
},
onStateChange : function(aProgress,aRequest,aFlag,aStatus) {return 0;},

onLocationChange : function(aProgress,aRequest,aLocation) {
return 0;
},
onProgressChange : function(a,b,c,d,e,f){},
onStatusChange : function(a,b,c,d){},
onSecurityChange : function(a,b,c){},
onLinkIconAvailable : function(a){}
};

Jeremy Dunck - 29th April 2005 04:28

Some additional info can be found at mozillaZine: Just Before Page Load Event?

Tuesday, August 15, 2006

IE vs MIME headers

One of the most irritating and mysterious behaviors of IE is how it determines file type. The first thing it does is basically ignore the MIME type the server introduces the data with, then it samples the data and does whatever the hell it pleases.

Trying to support users who are trying to download CSV data, for example, but instead get it displayed in the browser can be incredibly time consuming. It's usually just easier to suggest they use Firefox.

Friday, July 14, 2006

How to force an install of IE7 beta 3

For those that had the same problem I did, the IE7b3 installer complaining that Internet Explorer 7 is already installed on this machine, despite the fact that I uninstalled beta 2 from the Add or Remove Programs Control Panel without error (though clearly far too fast to have actually done anything), simply follow these instructions:

  1. Delete or rename C:\Program Files\Internet Explorer\iexplore.exe.

Now the installer will work fine.

Monday, May 08, 2006

The Best Several Things About Tight Web Browser Integration

  1. When a web script is caught in a loop, it will likely freeze your whole desktop.
  2. Two completely different applications, with totally different security needs and usage patterns, share resources.
  3. While debugging your ASP.NET app using Visual Studio, you cannot access your filesystem using Explorer.

Saturday, April 15, 2006

No shortcuts in .NET?

There is no class in the .NET SDK to read or write shortcuts (.lnk files)! Apparently, people just use the WSH Shell COM through interop [2], which seems like way too much overhead to me.

Thursday, March 30, 2006

Safari Date bug

The parameter for Date.setDate() is converted to a signed byte integer in Safari. This means that it can only be called with numbers from -128 to 127; all other values "roll over" into that range.

So, in Safari:

dt.setDate(128) = dt.setDate(-128)
dt.setDate(129) = dt.setDate(-127)
dt.setDate(130) = dt.setDate(-126)
...
dt.setDate(254) = dt.setDate(-2)
dt.setDate(255) = dt.setDate(-1)
dt.setDate(256) = dt.setDate(0)
dt.setDate(257) = dt.setDate(1)
dt.setDate(258) = dt.setDate(2)
dt.setDate(259) = dt.setDate(3)
...

Months and years/leap years are not exact, unless you use approximate mean months (30.436875) or mean years (365.2425), which can lead to rounding errors. So, if you need to add an arbitrary, exact time period to a date, the easiest way is dt.setDate(dt.getDate()+n), which even works for large values of n, since month and year rollovers are handled automatically.

Unfortunately, the Date.setDate() bug in Safari severely restricts the range of time that can be added to a date; only 96 (31 + 96 = 127) or fewer days can be reliably added. To work around this issue, something like this must be used:

function addDays(d,D)
{
var x= new Date(2000,1,1), y= new Date(2000,1,1);
if(x.setDate(128) > y.valueOf())
{ D.setDate(D.getDate()+d); return D; }
// Safari setDate(uint8) workaround
if(d < 0)
for(var i= -97; d < i; d-= i)
D.setDate(D.getDate()+i);
else
for(var i= 96; d > i; d-= i)
D.setDate(D.getDate()+i);
D.setDate(D.getDate()+d);
return D;
}

Thursday, March 23, 2006

IE7 Mar 20 beta Details

howtocreate.co.uk has a good analysis of IE7 changes.

MIX06 Notes: IE7 Mar 20 beta 2

IE7 now has support for min/max-width/height.

I have to say, though there is still a long way to go for full CSS2.1, XHTML, and other support, what I heard from the folks at Microsoft is very encouraging. I expect IE7.5 and IE8 to really raise the current lowest-common-denominator web client into a competitive position again.

Tuesday, January 31, 2006

IE7 beta 2

Fixed!

Still conspicuously missing:

More tests to follow...