Eric Schrock's Blog

Real life obfuscated code

July 1, 2004

In a departure from my usual Solaris propaganda, I thought I’d try a little bit of history. This entry is aimed at all of you C programmers out there that enjoy the novelty of Obfuscated C. If you think you’re a real C hacker, and haven’t heard of the obfuscated C contenst, then you need to spend a few hours browsing their archives of past winners1.

If you’ve been reading manpages on your UNIX system, you’ve probably been using some form of troff2. This is an early typesetting language processor, dating back to pre-UNIX days. You can find some history here. The nroff and troff commands are essentially the same; they are built largely from the same source and differ only in their options and output formats.

The original troff was written by Joe F. Ossanna in assembly language for the PDP-11 in the early 70s. Along came this whizzy portable language known as C, so Ossana rewrote his formatting program. However, it was less of a rewrite and more of a direct translation of the assembly code. The result is a truly incomprehensible tangle of C code, almost completely uncommented. To top it off, Ossana was tragically killed in a car accident in 1977. Rumour has it that attempts were made to enhance troff, before Brian Kernighan caved in and rewrote it from scratch as ditroff.

If you’re curious just how incomprehensible 7000 lines of uncommented C code can be, you can find a later version of it from The Unix Tree, an invaluable resource for the nostalgic among us. To begin with, the files are named n1.c, n2.c, etc. To quote from ‘n6.c’:

setch(){
register i,*j,k;
extern int chtab[];
if((i = getrq()) == 0)return(0);
for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0);
k = *(++j) | chbits;
return(k);
}
find(i,j)
int i,j[];
{
register k;
if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k);
for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1);
return(k);
}

If this doesn’t convince you to write well-structured, well-commented code, I don’t know what will. The scary thing is that there are at least 18 bugs in our database open against nroff or troff; one of the side-effects of promising full backwards compatibility. Anyone who has the courage to putback nroff changes earns a badge of honor here – it is a dark place that has claimed the free time of a few brave programmers3. Whenever an open bug report includes such choice phrases as this, you know you’re in trouble:

I’ve seen this problem on non-Sun Unix as well, like Ultrix 3.1 so the problem likely came from Berkeley. The System V version of *roff (ditroff ?) doesn’t have this problem.


1One of my personal favorites is this little gem, a 2000 winner ‘natori’. It should be a full moon tomorrow night…

#include <stdio.h>
#include <math.h>
double l;main(_,o,O){return putchar((_--+22&&_+44&&main(_,-43,_),_&&o)?(main(-43,
++o,O),((l=(o+21)/sqrt(3-O*22-O*O),l*l<4&&(fabs(((time(0)-607728)%2551443)/
405859.-4.7+acos(l/2))<1.57))[" #"])):10);}

2On Solaris, most manpages are written in SGML, and can be found in /usr/share/man/sman*.

3I’d like to think that the x86 disassembler is a close second, but maybe that’s just because I’m a survivor.

3 Responses

  1. My favourite from this family of commands is tbl(1)’s t..c, which is–you guessed it–a header file. (Counting t..c, tbl has 22 files with the pattern t?.c.)

  2. Now I know why I kept my sanity all these years… because I only looked at the groff sources. 🙂
    Thanks for sharing this interesting stuff, Eric!

  3. What you may not know is that the author, Joseph Ossana, died tragically. Although accounts vary, it’s reported that Brian Kernighan attempted to rewrite troff and nroff to remove some of their “obvious deficiencies”, but was so overwhelmed by the code that he gave up, and settled for tacking on the features he needed. After learning this story we joked that anyone modifying the nroff and troff source would be haunted by the ghost of Ossana. Coincidentally, my recent blog entry details a project in which I actually _did_ modify nroff and troff albeit only minimally to make them work with nohup and the new in Solaris 9 nohup -p: http://blogs.sun.com/roller/page/ahl/20040701

Recent Posts

April 21, 2013
February 28, 2013
August 14, 2012
July 28, 2012

Archives