With all the shiny client-side browser toys out there, many people forget about the dark underbelly of the web. As neat as it is that you can make a web brower act like a windowing system, dynamic sites are still powered by back-end applications; which is to say, powered by evil.

Now there are different levels of evil. Ruby is normally elegant but resource intensive. PHP was designed as an example of how not to name functions. Perl has its own special circle, ancient and full of strange characters. If you want real evil, though, you have to find a web application written in C.

When Paul briefly took the reins of such a web application --- by which he means he threw in the towel after three weeks --- he learned that his company had a special spot in Hell. Written in plain C without any fancy framework, it was 40k lines of code spread over a single file: the Monolith. All of the HTML, JavaScript, and SQL was buried in the lowest levels as print statements; as a bouns, the site was frame-heavy. I'm told that the database integration code could drive the weak-minded to insanity.

It was deep in the bowels of this application that Paul discovered the "and counter."

  int and;
  char stmt[2048];

  and = 0;
  if ( GetField( "name_first") ) { and++; }
  if ( GetField( "name_last") ) { and++; }
  if ( GetField( "cust_id") ) { and++; }
  /* ... more terms ... */

 

Obviously, and counts the number of terms that are set by the web form. But why?

  if ( GetField( "name_first" ) ) {
      sprintf( stmt, "%s c_name_f = '%s'", stmt, GetField( "name_first" ) );
      if ( and ) {
          sprintf( stmt, "%s AND ", stmt );
          and--;
      }
  }

  if ( GetField( "name_last" ) ) {
      sprintf( stmt, "%s c_name_l = '%s'", stmt, GetField( "name_last" ) );
      if ( and ) {
          sprintf( stmt, "%s AND ", stmt );
          and--;
      }
  }

  /* ... more of the same ... */

 

The entire point of the aptly named counter was to make construct a valid WHERE clause without appending a spurious true to the end of the statement. The really cool part about this code is that it isn't just called in one place: it's called to construct most of the SQL queries that run every page-turn. Even more telling, GetField is a function that processes *environ looking for QUERY_STRING. Once found, that string is searched and a pointer to a copy of the value associated with the key is returned. This pointer is never freed.

The function contained a single, very helpful comment: "dynamic query hell." Actually, I should say "contains": this application was mostly copy-and-pasted from the main website code, which is still in production use.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!