The Daily Parker

Politics, Weather, Photography, and the Dog

About that iOS "flaw"

Security guru Bruce Schneier wonders if the iOS security flaw recently reported was deliberate:

Last October, I speculated on the best ways to go about designing and implementing a software backdoor. I suggested three characteristics of a good backdoor: low chance of discovery, high deniability if discovered, and minimal conspiracy to implement.

The critical iOS vulnerability that Apple patched last week is an excellent example. Look at the code. What caused the vulnerability is a single line of code: a second "goto fail;" statement. Since that statement isn't a conditional, it causes the whole procedure to terminate.

If the Apple auditing system is any good, they would be able to trace this errant goto line not just to the source-code check-in details, but to the specific login that made the change. And they would quickly know whether this was just an error, or a deliberate change by a bad actor. Does anyone know what's going on inside Apple?

Schneier has argued previously that the NSA's biggest mistake was dishonesty. Because we don't know what they're up to, and because they've lied so often about it, people start to believe the worst about technology flaws. This Apple error could have been a stupid programmer error, merge conflict, or something in that category. But we no longer trust Apple to work in our best interests.

This is a sad state of affairs.

Error installing Entity Framework 6 in a very old Web project

I remember, back in .NET prehistory (2001), that one of .NET's biggest benefits was to be the end of DLL hell. Yet I spent half an hour this afternoon trying to get a common package (Entity Framework 6) to install in a project that never had that package in the first place—because of a version conflict with .NET itself.

When I tried to install EF6, the NuGet package installer failed the installation with the message "This operation would create an incorrectly structured document". A quick check of StackOverflow suggested a couple of possible causes:

  • The Entity Framework installer creates an invalid web.config file because it gets confused about the older project's XML namespaces.
  • The EF installer chokes on .NET 4.5 and .NET 4.5.1 because it's broken.

Anyone who's spent time with Microsoft products should immediately suspect that hypothesis #2 is unlikely. No, seriously: Microsoft releases things that have bad usability, rude behavior, and incomplete features all the time, but they have some incredible QA people. This fits that pattern: the installer script works fine. It just has pretty dismal error reporting.

So after removing every trace of EF from the relevant files, and downgrading the app to .NET 4.0 from .NET 4.5.1, EF still wouldn't install. Only at this point did I start thinking about the problem.

Let's review: I had an error message about an incorrectly-structured document. The document in question was almost certainly web.config, which I could tell because the EF6 installation kept changing it. The web.config file is an XML document. XML allows you to specify a namespace. This particular XML document had a namespace defined. A Stack Overflow commenter had mentioned namespaces. Um...

At this point I changed the web.config header element from this:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

to this

<configuration>

That fixed it.

The moral of this story: read error messages carefully, form hypotheses based on the data you have available, and even before that, stop and think. And even if you're not a Microsoft developer working on NuGet package installer scripts, always give as much detail as possible in error messages, so that developers who read them can spend less time trying to understand why the operation they thought was simple took so long to accomplish.

Regular readers of this blog know how irritated I get when error messages don't actually explain the error. I'm on developers for this all the time. It's rude; it's lazy; it costs people irrecoverable time. This is one of those times.

To Git or not to Git...

I'm torn.

Or I'm a dinosaur. Or I'm a Perceiver. Or I'm a senior software development manager who's sick of changing technologies.

My current drama is between continuing to use Mercurial on one hand, and switching to Git on the other. Both are distributed version control systems, so both enable a load of flexibility in single- or multi-developer workflows. I know that sounds like jargon, so let me explain.

No, there is too much; let me sum up: If you don't have to share every little change you make to a software project, everyone is better off.

The cold war between these two products has created two problems that appear to have nothing to do with each other:

  • We have multiple software projects that we have to continue to support in production while we build entirely new hunks of them (which will take months); and
  • All of the cool tools for integration and deployment work with Git, while not all of them work with Mercurial.

I suppose I shouldn't be surprised. I chose Betamax and Laserdisc as well. I have a real weakness for the best technical solution, even while the popular solution takes the lead. (Both Betamax and LaserDisc had superior audio and slightly better video than the products that defeated them. At least I held off choosing between HD DVD and Blu-Ray until one of them was cold and dead in the ground.)

I digress.

I'm annoyed that Git is moving so far ahead of Mercurial that it's becoming an argument to use Mercurial. I assert this is an argument to popularity, not to logic. But I also get really tired of swimming upstream, and if Microsoft, Bitbucket, and a bunch of other companies are pushing a technology, who am I to blow against the wind?

A conclusion, to the extent possible, will follow shortly.

Another bit of sanity brought to you by unit testing

I just saved myself hours of pain by creating a unit test around a simple method that turned out to have a subtle bug.

The method in question calculates the price difference between two subscriptions for a product. If you're using the product, and you use more of it, the cost goes up. Every day, the application looks to make sure you're only using your allotted amount. If you go over, you get automatically bumped to the next subscription level and charged the difference, pro-rated by how much of the subscription term is left.

Here's the basic code:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   newTier.MonthlyPrice - currentTier.MonthlyPrice;

All well and good, except MonthlyPrice, for reasons known only to the previous developer, is nullable. So in order to prevent an ugly error message, I made sure it could never be null using the ?? operator:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   newTier.MonthlyPrice ?? 0m - currentTier.MonthlyPrice ?? 0m;

Do you see the problem? I didn't. But I learned today that - takes precedence over ??. So here's the correction:

var delta = subscription.IsAnnual ? 
   newTier.AnnualPrice - currentTier.AnnualPrice : 
   (newTier.MonthlyPrice ?? 0m) - (currentTier.MonthlyPrice ?? 0m);

I discovered that when the unit test I wrote kept insisting that 6 - 6 = 6. This is because without the parentheses where I put them, the compiler thinks I meant this:

newTier.MonthlyPrice ?? ((0m - currentTier.MonthlyPrice) ?? 0m)

In English, the compiler thought my first attempt meant, "Take the new monthly price, except if it's null, in which case take zero minus the old monthly price, unless that's null too, in which case take zero." What I meant, and what my correction means, is, "Take the new monthly price, or zero if it's null, and subtract the old monthly price (or zero if that's null)."

I'm glad I use NUnit.

Bing Maps on Windows 8 #fail

I have an HTC Windows 8X phone. I work for a Microsoft Partner, so this seemed like a good idea at the time. After nearly a year, I can report that I am tired of this phone and want to go back to Android.

The one thing my phone does well is manage two Microsoft Exchange accounts. And it does Skydrive all right too. Those are Microsoft products, so Windows should handle them.

I find the touch-screen waaay too sensitive. It can't determine what letter I want more than half the time, and its auto-correct suggestions hardly ever make sense.

Bing, however, sucks ass, compared with Google. And there's no way to change the hyper-sensitive search button on the phone, which fires up Bing every time my thumb goes near the search icon. Sometimes when I'm trying to take a photo, or do something else that involves the phone not switching applications.

Bing Maps is even worse. I won't spend too much time on a rant when I could just show you.

Let me preface this by saying Seoul's WiFi situation is amazing. I have free WiFi nearly everywhere I go. Which is how I was able to run the following comparison.

Exhibit A, where the Bing Maps application thought I was this afternoon:

(Click for full-size image.)

Exhibit B, where Google Maps thought I was at the same moment:

Google wins.

Note that the Bing Maps application on my phone failed to produce a usable map; Bing Maps itself has the data. Here's what the Bing Maps website shows inside a browser window:

Attention, Microsoft: Having a nicely detailed map on my laptop does not help me when I'm in the middle of Gangnam. That's really exactly the moment that I want a good map.

Oh, and to add insult, Google Maps doesn't really work that well on the IE11 mobile browser. As in, it won't search unless you really make sure you touch exactly the right pixel on the screen.

My next phone? I'm going back to Android.

Things I found while listening to a conference call

Tomorrow afternoon is the Day of the Doctor already, and then in a little more than four days I'm off to faraway lands. Meanwhile, I'm watching a performance test that we'll repeat on Monday after we release a software upgrade.

So while riveted to this Live Meeting session, I am pointedly not reading these articles:

Perhaps more to the point, I'm not finishing up the release that will obviate the very performance test I'm watching right now. That is another story.

The first head rolls

The person most directly responsible for the HealthCare.gov debacle is "retiring:"

The chief information officer at the Centers for Medicare and Medicaid Services, whose office supervised creation of the troubled federal website for health insurance, is retiring, the Obama administration said Wednesday.

The official, Tony Trenkle, will step down on Nov. 15 “to take a position in the private sector,” said an email message circulated among agency employees.

As the agency’s top information officer, Mr. Trenkle supervised the spending of $2 billion a year on information technology products and services, including development of HealthCare.gov, the website for the new health insurance marketplace.

Sibelius, though. Why's she still around?

The usability of HealthCare.gov

Jakob Nielsen's company has written a detailed analysis of how the Federal Health Exchange screwed up usability:

The HealthCare.gov team has suffered what most web professionals fear most: launching a broken web application. This is particularly harrowing given the visibility of the website in question. The serious technical and data issues have been covered extensively in the media, so we won’t rehash those. Instead, in this article we focus on how to improve the account setup process. This is a user experience issue, but fixing it will also alleviate the site's capacity problems.

Account Set-up Usability is Mission Critical

Account setup is users’ first taste of a service. A suboptimal account setup can spawn 3 problems:

  • Increased service cost: When people can’t self-service online and you have no competitors, they call you. Call-center interaction is more expensive than web self-service. In 2008, Forrester estimated call-center calls to cost $5.50 per call versus 10 cents for a user who self-services online.
  • Increased cognitive strain: The instructions for creating usernames and password in this flow (which we address further along in this article) require a great deal of concentration, and if users don’t understand the instructions, they will need to keep creating usernames and passwords until they are accepted.
  • Halo Effect: Account setup is the first in a series of web-based interactions that users will need to conduct on HealthCare.gov. A poor experience with this first step will impact how people feel not only about subsequent interactions with the site, but how they feel about the service in general and the Affordable Care Act as a whole.

The discussion around our office hinges on two things other than usability: first, give us $2 million (of the $400 million they actually spent) and we'll build a much better site. Second, the biggest problems come from the insurance companies on the back end. Users don't care about that; they just want to get health insurance. As Krugman says, though, there really wasn't a way to get the insurance companies out of the equation, and that, more than anything, is the foundation of all these other problems.

jQuery: Party like it's 1989

Programming languages have come a long way since I banged out my first BASIC "Hello, World" in 1977. We have great compilers, wonderful editors, and strong typing.

In the past few years, jQuery and JSON, both based on JavaScript, have become ubiquitous. I use them all the time now.

jQuery and JSON are weakly-typed and late-bound. The practical effect of these characteristics is that you can introduce subtle, maddening bugs merely by changing the letter case of a single variable (e.g., from "ID" to "Id").

I've just spent three hours of a perfectly decent Sunday trying to find exactly that problem in some client code. And I want to punch someone.

Two things from this:

1. Use conventions consistently. I'm going to go through all the code we have and make sure that ID is always ID, not Id or id.

2. When debugging JSON, search backwards. I'll have more to say about that later, but my day would have involved much more walking Parker had I gone from the error symptom backwards to the code rather than trying to step through the code into the error.

OK, walkies now.

healthcare.gov is bad, but the Times should know better

I am agog at a bald impossibility in the New York Times' article today about the ACA exchange:

According to one specialist, the Web site contains about 500 million lines of software code. By comparison, a large bank’s computer system is typically about one-fifth that size.

There were three reporters in the byline, they have the entire Times infrastructure at their disposal, and still they have an unattributed "expert" opinion that the healthcare.gov codebase is 33 times larger than Linux. 500 MLOC? Why not just say "500 gazillion?" It's a total Dr. Evil moment.

Put in other terms: it's like someone describing a large construction project—a 20-story office building, say—as having 500 million rivets in it. A moment's thought would tell you that the mass of 500 million rivets would approach the steel output of South Korea for last month.

The second sentence is nonsense also. "A large bank's computer system?" Large banks have thousands of computer systems; which one did you mean? Back to my example: it's like comparing the 500-million-rivet office building to "a large bank's headquarters."

I wouldn't be so out of my head about this if it weren't the Times. But if they can't get this right, what hope does any non-technical person have of understanding the problem?

One last thing. We, the people of the United States, paid for this software. HHS needs to disclose the source code of this monster. Maybe if they open-sourced the thing, they could fix it faster.