Recently in Outstanding! Category

 

February 8, 2010

I recently had occasion to rent a car from Enterprise (long story). As I picked up the car and prepared to drive away, I noticed that the tank was only half full. I pointed this out to the customer service guy and he informed me that this was part of their new "half full/half empty policy", i.e., ordinarily you get the car full and you bring it back full. Here, they give it to you half full and you bring it back half full. I couldn't quite tell if this was what Enterprise always does now or just something they sometimes do, but while it seems superficially the same as the original policy, it's actually quite a bit worse for the renter.

With the old policy, life was simple: you found a gas station close to the car return, filled up the tank, maybe grabbed a receipt, and dropped the car off. By contrast, what happens here is that you drive around, filling up the tank if necessary, and at some point you need to return the car. If you're over 1/2 full then you just end up gifting the remainder to Enterprise (who can just fill up the tank completely and require the next customer to return it full). (What, you were going to drive the car around until you had burned up the gas? Or maybe you were going to siphon it out into some empty Gatorade bottles...) You could, of course, never fill the tank above 1/2 way, but this is a huge pain. Even if you're lucky enough to be at less than 1/2 full when you need to return the car, you're unlikely to be exactly at 1/2, in which case you need to put some gas in. You're reasonably likely to overshoot (again, taking gas out of the tank isn't easy.), in which case Enterprise again gets some free gas.

Either way, this is likely to be a win for Enterprise and a lose for you.

 

November 7, 2009

I happened to be leafing through Stroustrup and noticed that you can overload <code>< and >. This motivated me to write the following program:
#include <iostream>
#include <vector>
typedef int UINT4;

using namespace std; 

class Hack 
{
};

Hack & operator< (Hack &a , Hack &b)
{
 std::cerr << "LT operator\n";

 return a;
}

Hack & operator> (Hack &a, Hack &b)
{
 std::cerr << "RT operator\n";

 return a;
}


int main(int argc, char ** argv)
{
 Hack vector;
 Hack UINT4;
 Hack foo;
 
 vector<UINT4> foo;
 
 return(0);
}

Ask yourself what this code does.

The answer is that it outputs:

LT operator
RT operator

If you focus just on the line vector<UINT4> foo; this looks like a relatively ordinary template instantiation of a vector of type UINT4. This is perfectly normal C++ stuff. However if we expand the scope, it becomes clear that something different is going on: we've defined a new class called Hack and vector, UINT4, and foo are actually objects of type Hack. We've also overloaded the < and > operators. So, what's actually happening here is that we are doing function chaining: We perform operator > on the pair of objects UINT4 and foo. This returns a temporary object of type Hack (in this case the first argument but it doesn't matter). We then perform operator < on set and the temporary variable. And of course since these operators are just function calls, we can do any work we want in them. The examples print stuff to stderr, but that's just an example; you could do anything. And of course this code was written to be moderately transparent while making the point. You could obfuscate it much further with a little effort.

Outstanding!

 

Acknowledgment: Steve Checkoway pointed out to me that whatever crazy type resolution rules C++ follows here make the code work even with the definition of vendor and UINT4 at the top of file. My original version didn't have these and so alleged vector declaration in main wasn't really valid without the definition of Hack

UPDATE Oh great. HTML screws up anything with <foo>. Fixed now.

 

August 2, 2009

Mrs. Guesswork is flying in from Stockholm today, scheduled to arrive tonight around 10. You can't trust the schedules on transcon flights, so I check things out on the Delta site, which tells me it's an hour late, currently over Colorado and due in at 11:09. No problem, I'll watch Anthony Bourdain for a while and then head over. Around 9:15 I check again and (gulp!) it's now on time. Planes don't fly that fast, but it's not at all out of the question that Delta just screwed up here, so I'll just head over.

Right before I leave for SFO, I check again. The flights still on time, but then I notice something screwy: the flight is dated August 3rd, not August 2nd. I go back to the main page where you enter the flight #, and here's what it offers me:

  • Yesterday Aug 02
  • Today Aug 03
  • Tomorrow Aug 04

At this point it should be obvious what happened: Delta is based in Georgia, and in Georgia it's tomorrow, so naturally the site decided that's what I was interested in, despite the fact that that flight takes off something like 19 hours and today's flight is actually in the freaking air. Outstanding!

 

April 1, 2009

I'm experimentally trying using a task management app—not planning to do any sort of GTD thing, just looking for a little technical help with keeping track of all the crap I have to do. The general consensus seems to be for either Things or OmniFocus. and somewhat arbitrarily I selected Things: it's cheaper and seems a bit simpler to use. So far it's working fine, and I figured it was time to buy the iPhone app that goes along with it (OF has this as well).

Here's where things start to go off the rails. Once you have the iPhone app, you want it to sync up with the app on your computer: otherwise you have two disjoint systems, which is pretty useless. Unfortunately, it seemms that third party apps apparently can't sync with your computer the way that Apple apps sync, so the vendors need to come up with some hacky network-based scheme. Things' version seems to rely on Bonjour discovery and OF uses a WebDAV server. I don't really want to set up a WebDAV server somewhere and I'm way too paranoid to want to have random apps on my machine talking to random other computers on my network; that's why I have a firewall, after all. So, the bottom line is I'm hosed. A little bit of web searching quickly reveals hordes of people complaining about this (indeed, at least one of the early hits is about Things).

As far as I can tell, this is a basic limitation of the iPhone, but it's not clear to me if it's something Apple really doesn't want you to do or they just haven't gotten around to offering it yet. In either case, it's not very convenient.

 

March 19, 2009

Can someone explain to me why when when I go to download Firefox, Xcode, or a bunch of other software for that matter, it happens over HTTP and not HTTPS? Remember, I'm about to install and run this software on my computer: if an attacker has managed to hijack my connection, they can get me to run anything they want. But nooo.... Even if you connect to the site with HTTPS, it redirects you to HTTP to download your file. There are obvious reasons to favor HTTP over HTTPS, namely performance and allowing mirrors. On the other hand, that makes the need for publication of the digest even more critical, since it sucks to have to trust the mirror.

If you're going to use mirrors, the right thing to do here is to public a digest of the file on an HTTPS-accessible page (remember: these sites already will let you access them over HTTPS, so this doesn't make the situation worse). This would let users download the file from a mirror and then check the digest against the master site. I don't see digests on either site, though. It could just be that I'm missing it, but then surely lots of others are as well.

 

February 25, 2009

I've got some code that needs to convert an IP address into a string. This is one of those cases where there's a twisty maze of APIs, all slightly different. The traditional API here is:

    char *
    inet_ntoa(struct in_addr in);

inet_ntoa() has two deficiencies, one important and one trivial: it doesn't support IPv6 and it returns a pointer to a statically allocated buffer, so it's not thread safe (I'll let you figure out which is which). Luckily, there's another API: addr2ascii():

    char *
    addr2ascii(int af, const void *addrp, int len, char *buf);

If you pass buf=0, addr2ascii() will return a pointer to a static buffer like inet_ntoa(). However, if you pass it an allocated buffer it will return the result in buf. Unfortunately, if you actually try to use addr2ascii() in threaded code you will quickly discover something unpleasant, at least on FreeBSD: you occasionally get the result "[inet_ntoa error]" or some fraction thereof. The answer is hidden in the EXAMPLES section of the man page:

In actuality, this cannot be done because addr2ascii() and ascii2addr() are implemented in terms of the inet(3) functions, rather than the other way around.

More specifically, on FreeBSD, it looks like this:

    case AF_INET:
        if (len != sizeof(struct in_addr)) {
	    errno = ENAMETOOLONG;
            return 0;
        }
        strcpy(buf, inet_ntoa(*(const struct in_addr *)addrp));
        break;

In other words, even though addr2ascii() doesn't explicitly use a static buffer, since it depends on inet_ntoa() it's still not thread safe. In order to get thread safety, you need to use yet another API:

    const char *
    inet_ntop(int af, const void *restrict src, char *restrict dst,
        socklen_t size);

Outstanding!

UPDATE: Clarified that this is a problem on FreeBSD. I don't know if it's an issue on all other platforms. Linux, for instance, doesn't have addr2ascii()
UPDATE2: Trivial vs. important.

 

January 26, 2009

Rep. Peter King (R-NY) has introduced the Camera Phone Predator Act that would require camera phones to emit an audible indication whenever a picture is taken:
SEC. 2. FINDING.
Congress finds that children and adolescents have been exploited by photographs taken in dressing rooms and public places with the use of a camera phone.

SEC. 3. AUDIBLE SOUND STANDARD.
(a) Requirement- Beginning 1 year after the date of enactment of this Act, any mobile phone containing a digital camera that is manufactured for sale in the United States shall sound a tone or other sound audible within a reasonable radius of the phone whenever a photograph is taken with the camera in such phone. A mobile phone manufactured after such date shall not be equipped with a means of disabling or silencing such tone or sound.
(b) Enforcement by Consumer Product Safety Commission- The requirement in subsection (a) shall be treated as a consumer product safety standard promulgated by the Consumer Product Safety Commission under section 7 of the Consumer Product Safety Act (15 U.S.C. 2056). A violation of subsection (a) shall be enforced by the Commission under section 19 of such Act (15 U.S.C. 2068).

OK, so the value proposition for this is something like "protects children (think of the children!) from surreptitious photography". Except that it doesn't, because the bill doesn't apply to non-camera phones, which can be made just as small as camera phones, so if you're willing to plonk down $150 or so for a compact camera, you can evade this restriction and get much higher quality pictures. So, we need to sharpen the value proposition somewhat, to something like "protects children from surreptitious photography by people without digital cameras."

And of course, despite the "no disabling" provision, it's not like the tone is an essential function of the camera like the sound of a physical shutter release, it's just a speaker. So, unless you're going to totally redesign the phone, the miscreants can just open the phone, disable the speaker, and go to town. It's true this does render your phone useless as a phone, but seeing as used Motorola Razrs (remember, you don't need to connect it to the network) go for $30 or so on eBay, this isn't much of a problem. We need to revise the value proposition yet again to something like "protects children from surreptitious photography by people without digital cameras or who don't have $30 and a screwdriver."

Actually, it's even worse than that, since newer camera phones will do video recording, it's going to be pretty unacceptable to have it making an annoying noise the whole time it's being used. So, now we've got something like "protects children from surreptitious photography by people without digital cameras or who don't have $30 and a screwdriver, and whose camera phones don't take video." And let's not even talk about people who are willing to replace the software on their phones.

Other than that, this seems like a great idea.

Acknowledgement: I borrowed this argument technique from Allan Schiffman.

 

January 14, 2009

As I mentioned earlier, the IETF managed to pass copyright terms that more or less precluded the preparation of revisions of any existing standard. Opinions differ about whether this was understood before it was passed, (see the comments on the linked post), but it seems clear that many IETFers didn't understand the implications of the new requirements when they were published. As far as I can tell, potential submissions fall into three categories:

  • Documents which contain all new text and which can be safely submitted.
  • Documents which contain at least some old text but the new contributors aren't paying attention and submit them anyway.
  • Documents which contain at least some old text and are being held because they can't be safely submitted.

In principle, there might be a fourth category: documents which contain old text but where the contributors have obtained licenses from all the copyright holders. Unfortunately, the form that the IETF meant to provide for this purpose is, uh, broken so you're kind of on your own, unless, that is, you can convince people to sign a blank signature page. I'm not aware of any documents that fall into this category, but maybe there are some. In any case, I know a number of authors who are holding back documents because they don't believe they can obtain the necessary rights.

The current state of play is that the IETF Trustees have proposed some new boilerplate that will go onto submissions that more or less disclaims the 5378 rights grants. Unfortunately, the current text is inadequate and it's not clear when new text will be posted, let alone approved. IETF San Francisco (March) may turn out to be pretty interesting.

 

January 8, 2009

I recently had to send my Macbook Air in for repair and as a precaution I burned most of my data off the hard drive. Of course, when it came back I wanted to restore some but not all of my data. I have Time Machine backups, but since I actually only want some of the data and I want new versions of the software, I decided to treat this as a new machine install. Naturally, I figured I could just use iTunes to sync my data off my iPhone. In principle this should work fine. In practice, not so much.

The first problem I had when I plugged things in and pressed sync is that iTunes decided not to actually copy my calendar, contacts, etc. off. After a few minutes I remembered that you have to actually frob some button in a dialog for each of these. Once I had that figured out I tried to sync it again and after asking me if I realized that I was massively changing the data on my computer (which, remember, knows nothing at this point) it just popped up the useless progress bar and spun. And spun. For hours. I tried this a few times with the same results. At this point I figured I had been bitten by the dreaded slow iPhone sync, and was all ready to start trolling my disk for crash files to delete, slaughter a rubber chicken, etc. when somehow I noticed that hiding under all my other windows was a dialog saying "hey, you know you're replacing the contacts list on your computer with the one on your iPhone, right". Clicking that dialog made everything proceed in a few seconds. Remind me again why that dialog isn't modal? The spinning progress bar isn't exactly the UI indicator you would ordinarily use to indicate that I needed to click on some button. For that matter, why do I need to click this dialog at all? I just installed the operating system: why wouldn't I want to copy stuff off my phone onto my totally empty calendar and contact list?

 

January 7, 2009

Pete Lindstrom points to an article about what went wrong with Twitter. The short story: one of the admins had a weak password and Twitter has no limited try lockout on their system, so the attacker was able to mount an online dictionary attack. He wasn't even trying to crack an admin account; he just got lucky. Outstanding!

UPDATE: Fixed Pete's name. I'd thinkoed it...