Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to safely escape a string from C++

Tags:

c++

c

linux

shell

I'm writing a simple program to browse the local network and pass on filenames to mplayer using "system". However, sometimes filenames contain spaces or quotes. Obviously I could write my own function to escape those, but I'm not sure exactly what characters do or do not need escaping.

Is there a function available in the CRT or somewhere in the linux headers to safely escape a string to pass to the command line ?

like image 662
Frans-Willem Avatar asked Nov 13 '08 19:11

Frans-Willem


People also ask

How do you escape a string?

In the platform, the backslash character ( \ ) is used to escape values within strings. The character following the escaping character is treated as a string literal.

How do you escape a string in C #?

"; C# includes escaping character \ (backslash) before these special characters to include in a string. Use backslash \ before double quotes and some special characters such as \,\n,\r,\t, etc. to include it in a string.

What is the '\ n escape character?

Escape sequences are used inside strings, not just those for printf, to represent special characters. In particular, the \n escape sequence represents the newline character.


2 Answers

Other answers include this fork and exec solution, but I claim that this is the only right way to do it.

Escaping shell arguments is prone to bugs and a waste of time, just as trying to escape SQL parameters is a silly idea when safer and more efficient parameter binding APIs exist.

Here is a sample function:

void play(const char *path)
{
    /* Fork, then exec */
    pid = fork();

    if( pid < 0 ) { 
        /* This is an error! */
        return;
    }   

    if( pid == 0 ) { 
        /* This is the child */
        freopen( "/dev/null", "r", stdin );
        freopen( "/dev/null", "w", stdout );
        freopen( "/dev/null", "w", stderr );

        execlp( "mplayer", "mplayer", path, (char *)0 );
        /* This is also an error! */
        return;
    }
}
like image 193
Zan Lynx Avatar answered Sep 21 '22 15:09

Zan Lynx


There isn't a single solution that works everywhere because different shells have different ideas of what special characters are and how they are interpreted. For bash, you could probably get away with surrounding the entire filename in single quotes after replacing every single quote in the file name with '"'"' (the first single quote stops the sequence, the "'" appends the literal single quote to the string, the final single quote starts the quoted sequence again). A better solution would be to find a way to call the program without using system, such as by using fork with one of the exec functions so there is no shell interpolation.

like image 32
Robert Gamble Avatar answered Sep 23 '22 15:09

Robert Gamble