Archive for the ‘Vienna’ Category

Vienna 2.3.2 security update

Monday, July 27th, 2009

I’ve just released the security update Vienna 2.3.2. Security is no laughing matter, so all Vienna users need to update to version 2.3.2. Release notes are here.

The technical details of the vulnerability are instructive. The problem was this line of code:

returnCode = NSRunAlertPanel(alertTitle, alertBody, NSLocalizedString(@"Delete", nil), NSLocalizedString(@"Cancel", nil), nil);

Well, that’s not entirely true. The problem was that line combined with certain assignments of alertBody, for example:

alertBody = [NSString stringWithFormat:@"Are you sure you want to unsubscribe from \"%@\"? This operation will delete all cached articles.", [folder name]];

By default, the value of [folder name] comes from a most trustworthy source: the internet. If, by chance or design, the name contains conversion specifiers, you’re in big trouble. For a discussion of this kind of vulnerability, see Apple’s Secure Coding Guide. The Secure Coding Guide is a must read for Mac Developers. (I also recommend this. Tell them Jeff sent you.)

One simple fix for the vulnerability is as follows:

returnCode = NSRunAlertPanel(alertTitle, @"%@", NSLocalizedString(@"Delete", nil), NSLocalizedString(@"Cancel", nil), nil, alertBody);

With this fix, the alertBody string — which contains the unvalidated folder name — is no longer treated as a format string.

You need to be very careful about using NSRunAlertPanel() and similar functions. Unfortunately, the API and documentation are quite bad. The Discussion doesn’t even mention that the second argument is a format string; for that, you have to read the documentation for another function. Furthermore, it’s absolutely insane to put three unrelated items between the format string and the optional arguments for the format string.

As you know, however, you go to war with the API you have, not the API you might want or wish to have at a later time.

Cocoa memory management for smarties, Part 2: working with a nib

Monday, August 25th, 2008

Well, it’s back to work for the moment. I was offered the VP slot, but I had to turn it down because they refused to accept the NDA: my name would be on the ticket, but nobody could talk about me publicly. Also, they wouldn’t get rid of the brown M&Ms. I am waiting for an offer by email from another guy, but I don’t hold out much hope, since I’m also waiting for him to learn how to use email.

In part 1 of this series I talked about Cocoa memory management. For a summary of that post, load it in your browser, select all, and pass it to the Summarize system service. And now for something completely the same, in part 2 I’m going to talk about Cocoa memory management. As you all know, I love nibs. I find them to be a very human-friendly interface, much like the gom jabbar. A nib file contains archived Objective-C objects that are instantiated when the nib is instantiated, so their memory needs to be managed just as objects instantiated programmatically. Fortunately, if the nib File’s Owner is an NSWindowController or (new in Leopard) NSViewController, the File’s Owner takes care of the memory management automatically. Otherwise, it’s your job.

According to the documentation, Objects in a nib file are initially created with a retain count of 1. As it rebuilds the object hierarchy, however, Cocoa autoreleases any objects that have a parent or owning object, such as views nested inside view hierarchies. By the time the nib-loading code is complete, only the top-level objects in the nib file have a positive retain count and no owning object. This makes the top-level objects a potential memory leak if your code does not assume responsibility for them. If you look at your nib with the icon view in Interface Builder, the top-level objects consist of everything except the proxy objects such as File’s Owner, First Responder, and (new in Leopard) Application. Thus, top-level objects include not only windows but also contextual menus, array controllers, etc. For example, Vienna’s MainMenu.nib, pictured below, contains 14 top-level objects. (Kids, don’t try this at home.)

MainMenu.nib

By the way, the MainMenu.nib file, or whatever is specified by NSMainNibFile in Info.plist, is actually a special case, because the File’s Owner is NSApplication (or whatever is specified by NSPrincipalClass). You don’t need to worry about its memory management either, although the objects in the nib will usually remain in memory for the lifetime of the app. On termination, NSApplication may or may not choose to release those objects, as it pleases, so don’t depend on any code in dealloc. Cleaning up memory on app termination is like sweeping your floor right before a tornado hits.

In order to manage the memory of the nib’s top-level objects, you’ll need a reference to them. The method -[NSNib instantiateNibWithOwner: topLevelObjects:] is handy in this respect. The documentation of the (NSArray **) topLevelObjects argument may be a little confusing, though: On input, a variable capable of holding an NSArray object. On output, this variable contains an autoreleased NSArray object containing the top-level objects from the nib file. Although the NSArray is autoreleased, the top-level objects themselves are not. Each object in the NSArray will have a retain count of at least 2. Thus, after the NSArray is deallocated and releases its objects, they will each still have a retain count of at least 1. A typical way to handle this is as follows.


@interface MyObject : NSObject
{ NSArray * _topLevelObjects; }
@end

@implementation MyObject

-(id) init
{
	self = [super init];
	if (self)
	{
		NSNib * nib = [[[NSNib alloc] initWithNibNamed:@"MyNib" bundle:nil] autorelease];
		if (nib && [nib instantiateNibWithOwner:self topLevelObjects:&_topLevelObjects])
		{
			// The array is autoreleased, so we need to retain it.
			// Release the objects now so that they'll be deallocated along with the array.
			[[_topLevelObjects retain] makeObjectsPerformSelector:@selector(release)];
		}
	}
	return self;
}

-(void) dealloc
{
	[_topLevelObjects release];
	[super dealloc];
}

@end

If you use a different method to instantiate the nib, such as +[NSBundle loadNibNamed:owner:], or if you don’t want to keep an array of the top-level objects, you’ll need to create an IBOutlet for each top-level object in the nib and release the objects in dealloc along with any other ivars.

A major caveat for do-it-yourself nib loading is that even if you take care to release your top-level objects, you can still get a memory leak if you use Cocoa bindings in your nib. This occurs when an object in the nib binds to the File’s Owner. The File’s Owner never gets deallocated in this case, and thus neither do the top-level objects. Again, NSWindowController and NSViewController already take care of this problem automatically, but you’ll need to deal with it if the File’s Owner is not one of those classes or their subclasses. Basically, there are three possible solutions:

  1. Unbind the bindings programmatically. You’ll need to do this elsewhere than the File Owner’s dealloc, which won’t get called unless you unbind.
  2. Bind to a different object in the nib rather than to the File’s Owner.
  3. Don’t use Cocoa bindings and nibs, because they’re teh suck.

Slow news day: favorite feeds updated

Tuesday, August 5th, 2008

It’s been a while since I’ve updated my Favorite Feeds in the Downloads section of the sidebar of my blog front page. (Sounds like AppleScript, eh?) I would export from Vienna and update it every day, but I have to manually edit the .opml file first to remove embarrassing subscriptions such as porn and the New York Times. For your convenience and amusement, the latest version is up now.

WordPress hacking: more comments in your feeds

Sunday, 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!

Vienna not dead yet, but RIP Panther

Sunday, 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.

Cocoa Blogs free, as in beer

Sunday, 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!

News Flash: Vienna brings down the mighty NewsGator

Wednesday, January 9th, 2008

In an obvious gesture of defeat, NewsGator has announced that they — is a company a collective or an individual? — are no longer attempting to charge money for NetNewsWire. Their cover story is some mumbo-jumbo about “enterprise”. Sure, and Leopard was delayed by the iPhone. ;) What they would never admit publicly is that they realized it was pointless to compete against the best Mac RSS utility on the planet. Who would pay for NetNewsWire when Vienna is free? Not to mention open source! (Oops, I just mentioned it. I take it back.)

Let it not be said, however, that we are without pity for the downtrodden. On behalf of the Vienna developers, I apologize for destroying the commercial feed reader market. What else can I say? Ya gotta do what ya gotta do. Give the fans what they want. The battle has certainly made great entertainment, the classic David vs. Goliath tale. Once again, David (actually Jeff) has overcome insurmountable obstacles, beat overwhelming odds, leapt over tall buildings in a single bound, to emerge victorious. It’s always a thrill to see the underdog win … except the Miami Dolphins.

Yet I shall only allow myself a moment to rest on my laurels, to savor the sweet smell of success. (It smells a little like tequila, actually.) For I’ve already chosen my next target: outliners. Look out, OmniGroup!

Vienna 2.2.1 available now (and yesterday, and the day before)

Tuesday, December 4th, 2007

It should come as no surprise that Vienna 2.2.1 was released on Sunday. I’ve been too busy the last two days chipping my car out of the ice to write a post here. Release notes are available for the lazy, though real coders read the commit logs.

Contrary to expectations, this is not really a Leopard compatibility release. I would say that Vienna is not yet Leopard ready. On the other hand, I would also say that Leopard is not yet itself ready. So there you have it.

What ever happened to Cocoa Blogs?

Thursday, November 29th, 2007

It seems dead, though the clock is still ticking. (Countdown to extinction?) Anyway, I’ve just updated my own extensive list of cocoa blogs and other favorite feeds, which you can download from the Downloads section of my sidebar. FileMerge will reveal the changes in my all-important favor. Remember bloggers, X-Mas is coming soon, not to mention Y-Mas and Z-Mas. I’m keeping track of who’s naughty and nice — mostly by intercepting your wireless packets. If you’re nice, you’ll get a hot dog and a shake.

WordPress Bug Fix Near Saturday: props lapcat

Saturday, September 22nd, 2007

The network has decided to renew my series for at least one episode. WordPress 2.3 is approaching release, and I’m pleased with the progress that it has made in supporting syndicated feeds. The patch I submitted to fix the Atom feed modification date bug has been committed to the trunk. RSS 2.0 feeds still don’t give modification dates, but that could be considered a personal preference. (As can RSS 2.0 itself. Of course, no one would prefer the worse to the better, as Socrates would say, if he were 2500 years old and spoke English.)

Other syndication bugs that have been fixed in the trunk include checking the last modified date of posts rather than comments for comments feeds, an obsolete Atom feed template, and checking the last modified date of unapproved comments for comments feeds. WordPress 2.3 should be a good update for feed readers such as you and feed readers such as Vienna.

Time to go. Joan Cusack is calling again.