SECURITY ALERT: check your DNS servers

July 22nd, 2008

The full details of the infamous DNS vulnerability have been inadvertently disclosed. The post was pulled, but I can still read it in my Vienna database.

The vulnerability is bad, folks. I completely agree with the decision to keep the details secret while vendors patch their DNS servers. The secret is out now, though, so there’s no time to wait. Perform the web-based test of your DNS servers, and switch to different servers if the results are POOR. If you need to switch, one decent option is OpenDNS.

Laptop users should be especially careful, because your ISP changes when you take your computer to different locations. Even if you pass the test at home, you may be vulnerable at the coffee shop. I recommend hard-coding DNS server IP addresses in the Network pane of System Preferences. You might also want to check the DNS settings of any routers you use.

Compiler indirectives and metaphorical keypaths

July 2nd, 2008

I am, like, literally ROTFRTFMIMHOLOLYMMVIIRCFUBAROTOH!

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(likeNoWay:) name:@”ROTFRTFMIMHOLOLYMMVIIRCFUBAROTOH” object:nil];

A string literal is a sequence of characters enclosed in quote-unquote ‘\”quotation marks\”‘ (wiggles index and middle fingers). In the C programming language — so-named because its inventors lacked imagination — a string literal represents an array of char terminated by a null (or by a comma when the feeling’s not that strong). In the Objective-C programming language — otherwise known as The O.C. — a string literal in a compiler directive (e.g., @"NSBirdJustFlewIntoMyWindowException") defines a constant NSString object.

Chris Hanson and Sanjay Samani have offered some excellent advice about avoiding the use of these NSString literals in your method calls. The problem is that the compiler will accept pretty much any directive: with Objective-C 1.0 the compiler only warns about non-ASCII characters, and with Objective-C 2.0 it doesn’t even do that (for better or worse, but that’s a subject for a different post). Thus, if you happen to misspell a notification name, you’ll never know until your app misbehaves at runtime. I’m sorry, Dave, I’m afraid I can’t do that.

I recommend replacing NSString literals with macros or constant variables (huh?) wherever spelling matters. (Spelling matters everywhere. I’ve seen some pretty bad method names.) Here’s a little trick for handling arbitrary keypaths:

#define KEY1 @"key1"
#define KEY2 @"key2"
#define KEY3 @"key3"
#define DOT @"."

[self valueForKeyPath:KEY1 DOT KEY2 DOT KEY3];

Unfortunately, we’re still at the mercy of misspellings in nib bindings. Yet another reason to do without nibs. But that’s also a subject for a different post and horse of a different color (dried poop).

WordPress hacking: more comments in your feeds

June 15th, 2008

Unless you’re the Tolstoy of blogging — Does that even make sense? It’s like being the Gandhi of boxing — you’re probably not writing thirty WordPress posts a day. At my rate — the Def Leppard of blogging — I’m lucky to produce thirty a year (not counting my posts under the pen name “Arianna Huffington”). However, it is possible for one post to receive thirty comments in one day, especially if it contains provocative statements, e.g., AppleScript, Die! Die! Die! or Please leave your comments below. (This is assuming that you allow comments. And that someone reads your blog. And that the someone is not an NSA agent.)

Unfortunately, WordPress uses the same limit on the number of items in a syndicated feed for both the main post feed of the blog and for the comments feed of an individual post. By default, that limit is 10 items. Thus, if you try to follow an active comments thread on a post via the feed, you’re likely to miss comments (unless you’re one of the scourges of the internet who have their feed readers set to check for new articles every two minutes). It completely defeats the purpose of subscribing to the comments feed if you can’t track the comments with the feed. As a solution, you could raise the overall WordPress item limit, for both posts and comments, but this may increase the bandwidth of your web site significantly, enormously if you’re one of the angels of the internet who put the full text of their posts in the feed.

Fellow blogger Daniel Jalkut of Red Sweater Software has filed a feature request for a separate limit on comments feeds. However, you don’t need to wait until WordPress 2.7 for this request to be implemented, because you can implement it now by hacking your own WordPress installation. With Daniel’s help, I was able to get this to work in WordPress 2.5.1. You just need to modify one file, wp-includes/query.php. The ending of line 1380 in query.php is currently

	DESC LIMIT " . get_option('posts_per_rss'));

You need to modify it as below, replacing 100 with your desired item limit for comments feeds.

	DESC LIMIT 100");

You also need to modify the ending of line 1437, replacing

	DESC LIMIT " . get_option('posts_per_rss');

with

	DESC LIMIT 100";

That’s all there is to it! My usual disclaimers apply here: I take no responsibility for breaking anything of yours, for breaking anything of anyone else’s, or indeed for anything that happens in the universe. I do offer this guarantee: if my hack doesn’t work for you, I’ll gladly refund my consulting fee.

Please leave your comments below. AppleScript, Die! Die! Die!

I’m a Rogue

June 7th, 2008

I’m delighted to announce that I’ve been hired as Rogue Amoeba Employee 008. (Employee 007 is Longwell, Justin Longwell.) I’ll be working on Rogue Amoeba’s apps as a software engineer, as well as providing comic relief. Thanks to Alex, Paul, and Quentin for this once-in-a-lifetime opportunity. My coworkers at Rogue Amoeba Software, LLC include fellow bloggers Mike Ash and Guy English. Together we form perhaps the most talented group of Mac programmers outside of Apple. (Yes, I’m talking to you, Adobe and Microsoft.) Indeed, I haven’t seen such an array of stars in one place since the Ghostbusters music video.

I’ve joined Rogue Amoeba just in time to miss WWDC ‘08. In an earlier post, I mentioned that I left Marko Karppinen & Co. LLC just in time to miss WWDC ‘07. (I’ll make it there someday! :-( ) The question is, what have I been doing in the meantime? Backpacking through Europe? Rotting in Gitmo? Running for President? No, I’ve been working on super-secret projects for Francis Technical Services, LLC. Although FTS is a little-known company, its software is well-known, at least inside Apple. For example, FTS is responsible for Radar, the Apple-internal Cocoa app that opens when employees click on the funny-looking rdar://problem/ URLs you often see. The number at the end of the URL corresponds to the problem ID of the bugs you file on the web with Apple Bug Reporter (also known as RadarWeb). It’s useful to have one of these URLs available when communicating with Apple engineers, because their managers forbid them from lifting a finger without a Radar problem number.

While at FTS, I did some bug analysis for Radar: that is, analysis of bugs in Radar’s source code, not analysis of bugs in Radar’s database, to which as a contractor I had extremely limited access. However, I mostly worked on other projects, such as Radar’s sibling app Sonar. Apple’s DTS uses Sonar to communicate with ADC members (such as me!). If you’ve ever seen sonr://request/ URLs — the Mighty Quinn provides one in an Apple Mailing List post — those open in Sonar. (By the way, I’ve read all of your emails to DTS. No, you haven’t been accepted to the iPhone Developer Program. Stop whining.) Another project that I worked on was Merlin, an app for Apple’s Human Resources department. I think that Steve Jobs is doing an outstanding job at Apple, so before I left I used Merlin to double his annual salary.

I’d like to thank Dave Francis, the owner and founder of Francis Tech, for the opportunity to work there. Despite appearances, I’m not really the type to hop from job to job. I’ve just been looking for Mr. Right, LLC, a company to fall in love with, marry, and have baby apps with. (As for any other support claims, sorry Billie Jean.) I can see myself growing old with Rogue Amoeba. (Easy to see when you’re already old?) Besides, someone has to stick around and keep an eye on mikeash, stop him from taking over the world.

Now without further ado, please take out your credit card and buy some of our fine software. As a special bonus for our Leopard customers, your purchase will be (code-)signed by your favorite Rogue Amoeba star.

Vienna not dead yet, but RIP Panther

June 1st, 2008

Alas, poor Panther! I knew him, Horatio. You, Horatio, I don’t know so well, and you’re creeping me out. Why did you bring me to the cemetery?

The good news is that the first beta version of Vienna 2.3.0 is now available for download. Actually, it’s more of a zeta version, if you know what I mean. (You don’t.) The changes from 2.2.2 are listed in the release notes. The bad news is that Vienna 2.3 won’t run on Mac OS X Panther. Vienna 2.2.2 is the last release that supports Panther. That sucks, but if you’re still running 10.3.9, you probably don’t care much about the latest and greatest software anyway. Vienna 2.2.2 will continue to be available at Sourceforge.

Yeeha, Jester’s dead! I am dangerous, ice man.

SECURITY ALERT: Mac OS X 10.5.2 subverts FileVault

May 10th, 2008

I apologize for not posting this earlier. I’ve been extremely busy lately, and I had discussed the issue with someone who said that he or she (he) was going to post about it (but hasn’t).

The security alert is for FileVault users running Mac OS X 10.5.2. You thought that FileVault encrypted your personal data, right? Wrong! In Mac OS X 10.5.2, the location of the CFNetwork caches was moved from ~/Library/Caches, which is within your home directory and thus encrypted, to /private/var/folders, which is not within your home directory and thus not encrypted. This means that anyone with physical access to your hard drive could, for example, determine which URLs you’ve loaded, even if your computer is shut down.

Note that nothing about this change was mentioned in the Mac OS X 10.5.2 release notes.

For further reference on this issue, see the thread that began in the WebKit SDK mailing list and was moved by me to the Macintosh Network Programming mailing list. Thanks to Eric Long, who noticed the change in the first place, and Ron Hunsinger, who performed testing that I was too lazy to do. (In my defense, I haven’t yet migrated my FileVault account from Tiger to Leopard, so the issue doesn’t affect me directly.)

Cocoa Blogs free, as in beer

March 30th, 2008

Wait, beer is not free! Or so my bartender yelled last night as I ran out the door. (I also had one bourbon and one scotch.) The front page of Cocoa Blogs was already free, but the syndicated feed has only been free to contributors — kind of like Congress. Now Scott has decided (he is the decider) to make the feed available for free too. Indeed, new items are appearing in the feed. Remember, folks, you heard it here first. This is your Number 1 source for news, rumors, and outright lies.

My own long list of Cocoa blogs, including the Cocoa Blogs feed, can be downloaded for free from the “Favorite Feeds” link in the sidebar of my blog. The list is in convenient .opml format for import into your favorite free feed reader. There seem to be many choices nowadays. (Too bad that they all suck. Mine sucks the least, though.) The contents of my web site have been and always shall be free, as in loader. If I asked for contributions, that would just embolden the terrorists. Last call!

Stabs is deprecated

March 9th, 2008

This post is dedicated to E. Gary Gygax, the second greatest corrupter of youth in history. It’s about D&D, that is, DWARF and dSYM. As of 2008-02-27, the STABS debugging symbols format has been deprecated by Apple. The default value for the DEBUG_INFORMATION_FORMAT build setting in Xcode projects had been stabs, but now it’s time to move on. (I’m talking to you, Justin Long.) Our other options are dwarf or dwarf-with-dsym. Also cake or death.

With STABS, you could build the release version of your app with debugging symbols, make a copy of the executable MyApp.app/Contents/MacOS/MyApp to keep, strip the executable for shipping, and then use the unstripped executable for symbolizing crash reports by giving a space-separated list of stack trace addresses to the command-line tool atos. Unfortunately, atos cannot currently serve this purpose with DWARF. Unlike STABS, DWARF does not include the debugging symbols in the executable itself but merely includes references to the intermediate object files, which do contain debugging symbols. You can usually find these .o files in a sub-directory of the build/MyApp.build directory. If you delete the object files after building with dwarf, you won’t be able to step through your app’s code. (With stabs, the object files are refuse.) You also won’t be able to step through the code if you strip debugging symbols from your app, even if you keep the object files, because the references to the object files will be gone from the executable.

To avoid losing the debugging symbols for your app after stripping, you want to use the option dwarf-with-dsym. The DWARF with dSYM option performs an additional step beyond ordinary DWARF: it creates a separate MyApp.app.dSYM file that contains all of the debugging symbols for your app. In fact, the DWARF with dSYM option allows you to step through your code regardless of whether the executable is stripped! This is possible because gdb will look for the .dSYM file in the same directory as your app. It doesn’t need to know the name or location of the object files. If you don’t strip debugging symbols, you can use either the .o files or the .dSYM file for debugging, but for the local debug build of your app there’s no point in using dSYM, since that would just prolong your build time. You have better things to do than wait for builds, such as writing comments on Slashdot.

The trouble with atos is that it does not reliably find debugging information in .dSYM files for stripped executables. Although Apple’s documentation (as of 2007-04-02) says, “If you’re using DWARF dSYM files, you must be using the version of atos included in Xcode 3 (Mac OS X version 10.5)”, Apple’s engineers say, “The underlying framework that atos uses doesn’t support loading symbol names from dSYM files in Leopard.” In my testing, however, there doesn’t seem to be a difference between Leopard and Tiger, at least not with Xcode 2.5 on Tiger. On both Leopard and Tiger, atos successfully loads symbol names from .dSYM files (I deleted the .o files) for unstripped executables. For stripped executables, in contrast, atos frequently fails to load the symbol names, or even gives inaccurate results.

The CrashReporter Technical Note suggests loading your app and its .dSYM in gdb to translate stack trace addresses from crash reports. That’s like having to start your car in order to read the odometer. (Oh wait, I have to do that, Nissan!) An alternative method is the command-line tool dwarfdump. It requires only the .dSYM file, not a copy of your app, and its --lookup option will do the same job as gdb without the overhead.

Please note that by breathing, blinking, or moving at all, even to command-w this page, you thereby register your agreement not to disclose or discuss this information anywhere with anyone at any time, no matter the duress, torture, or water-boarding you may undergo to extract it. This agreement holds despite the fact that the information is publicly available on the internet for every person in the world to read. Failure to uphold this agreement will result in multiple, painful cat scratches, in certain cases leading to cat scratch fever.

The beach is open

March 1st, 2008

I know that March may be too early to think about going to the beach, but Code Beach does not require a tan, six-pack abs (so-called because beer drinkers usually have nice abs), or even swim trunks. No, it’s not for nudists, it’s for Mac developers! Nudist Mac developers, use your own discretion. The goal of Code Beach is to create a central repository where Mac developers can share pieces of useful code (like custom controls, formatters, categories) which is easier to search/use than forums or mailing lists. Brought to you by Briksoftware, Code Beach could use more traffic and more code. Don’t worry, there’s only one Shark, mostly harmless.

NSScrollView in a key view loop (or Fembot in a wet T-shirt)

February 20th, 2008

Now that the Pats have won the Super Bowl, Rudy has won the GOP nomination, and the Jedi have won the Clone Wars, all is right with the world (and the galaxy), so we can focus again on our lives, on our families, and most important, on Cocoa. If you’re a Cocoa developer, you are morally required to open System Preferences, Keyboard & Mouse, Keyboard Shortcuts and select All controls in Full keyboard access. This is not optional. If you do not comply, you will be driven out of the Continuum and forced to spend the rest of your pitiful mortal existence writing kernel extensions.

With the mandatory preference setting, you will observe the full Cocoa key view loop. Actually, it doesn’t have to be a loop: it could be a key view cul-de-sac. Anyway, Apple clearly wants developers to “leave the driving to us”, i.e.,

-[NSWindow setAutorecalculatesKeyViewLoop:YES]

because configuring and updating the key view loop can be a pita — like training a cat. The docs make it sound oh so easy, but that’s only because the docs don’t cover the complex or problematic cases. Suppose, for example, that you have a scroll view enclosing a view that contains multiple controls. You want the key view loop to follow a particular route both outside and inside the scroll view. How should you hook up the views in Interface Builder? (Or in code, when you’re working without a nib.)

I believe that the proper way to handle an NSScrollView in a key view loop is to ignore it. Walk by quickly without making eye contact. Whatever you do, don’t engage in conversation! Otherwise you’ll get invited to coffee or lunch. The reason you can ignore NSScrollView is that it never actually becomes the firstResponder of an NSWindow. The scroll view returns YES from acceptsFirstResponder if its documentView does, but if you then call -[NSWindow makeFirstResponder:] with the scroll view as argument, the window’s first responder will end up being not the scroll view itself but rather its document view.

This behavior is adequate if the document view is a single control such as an NSTableView or an NSTextView (though maddeningly, an NSTextView tends to interpret the tab key as, well, a tab). In the window nib, you can simply include the scroll view in the window’s key view loop, ignoring the document view, and when the window loads, the scroll view will automatically rearrange the key view loop to make its NSClipView the nextKeyView, followed by the document view and then the scroll view’s original nextKeyView. The scroll view and the clip view are superfluous in the key view loop, however, because only the document view becomes the first responder when tabbing through the window.

This behind-the-curtain key-view wizardry may seem impressive, but the scroll view is really deaf, dumb, and blind. It has no idea about any loop you’ve defined within the document view. There is no way to inform the scroll view of the beginning and end points of the ’sub-loop’. If you attempt to insert the scroll view containing your sub-loop into the window’s key view loop, it will turn into either a key view dead end within the scroll view or a key view overpass, depending on the configuration.

To avoid these problems, simply connect your views together in the key view loop as if the scroll view did not even exist. You know, like Mac OS X Tiger. (Of course the keyboard firmware update requires Quick Look and Time Machine!) Only the views that become first responder — as opposed to becomeFirstResponder — need to be hooked up. When a cat is lying on the trackpad, you will be thankful for setting the key view loops in your app, and so will your users. Cat-friendliness is in fact the most crucial consideration for designing both software and hardware.

I am saying that I will neither aspire to nor accept — I repeat, I will neither aspire to nor accept — the positions of President of the State Council and Commander in Chief. I will, on the other hand, host the Tonight Show if asked. Hasta la vista!