Today's code is only part of the WTF. The code is bad, it's incorrect, but the mistake is simple and easy to make.
Lowell was recently digging into a broken feature in a legacy C application. The specific error was a failure when invoking a sed
command from inside the application.
// use the following to remove embedded newlines: sed ':a;N;$!ba;s/\n,/,/g'
snprintf(command, sizeof(command),"sed -i ':a;N;$!ba;s/\n,/,/g' %s/%s.txt",path,file);
system(command);
While regular expressions have a reputation for being cryptic, this one is at least easy to read- or at least, easier to read than the pile of sed
flags that precede it. s/\n,/,/g
finds every newline character followed by a comma and replaces it ith just a comma. At least, that was the intent, but there's one problem with that- we're not calling sed
from inside the shell.
We're calling it from C, and C is going to interpret the \n
as a newline itself. The actual command which gets sent to the shell is:
sed -i ':a;N;$!ba;s/
,/,/g' /var/tmp/backup.txt
This completely broke one of the features of this legacy application. Specifically, as you might guess from the shell command above, the backup functionality. The application had the ability to backup its data in a way that would let users revert to prior application states or migrate to other hosts. The commit which introduced the sed
call broke that feature.
In 2018. For nearly three years, all of the customers running this application have been running it without backups.
Lowell sums it up:
The real WTF may be the first part of my reply: "Looks like backup was broken by a commit in December 2018. The 2014 version should work."