GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sun Sep 21, 2014 6:05 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: sprintf a filename
PostPosted: Tue Sep 18, 2012 8:58 pm 
Offline
GTK+ Guru

Joined: Sun Jul 08, 2012 3:14 pm
Posts: 107
Location: Coventry, UK
Sorry for putting a(nother) C question here. But since my goal is to get a widget work, I am humbly posting this, hoping some help.
I am trying to have something like:
Code:
if (gtk_dialog_run(GTK_DIALOG(pdialog)) == GTK_RESPONSE_ACCEPT) {
        pdfname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pdialog));
    }
    gtk_entry_set_text(GTK_ENTRY(entrypdf), pdfname);
    char pdfinfo[1028];
        sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
        g_print("%s", pdfinfo);
        system((char *) pdfinfo);


This works fine when the filename choosen has no space. If it has space,
as linux reads it as "file\ with\ space", pdfinfo is giving error.

I cannot open pdfinfo (in my knowledge) with fopen, as then,
Code:
sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
will give error, as I am printing a FILE as char.
what is the wayout?


Top
 Profile  
 
 Post subject: Re: sprintf a filename
PostPosted: Wed Sep 19, 2012 1:11 am 
Offline
GTK+ Guru

Joined: Fri Mar 25, 2011 5:16 pm
Posts: 177
Location: USA
I would not use sprintf(), according to "The GNU C Programming Tutorial"
Quote:
The sprintf ("string print formatted") command is similar to asprintf, except that it is much less safe.
...
This function will behave unpredictably if the string to which it is printing overlaps any of its arguments. It is dangerous because the characters output to the string may overflow it. This problem cannot be solved with the field width modifier to the conversion specifier, because only the minimum field width can be specified with it. To avoid this problem, it is better to use asprintf, but there is a lot of C code that still uses sprintf, so it is important to know about it.
http://www.crasseux.com/books/ctutorial/sprintf.html

It gets worse, there are also security concerns:
Quote:
The sprintf and vsprintf functions are easily misused in a manner which enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. Because sprintf and vsprintf assume an infinitely long string, callers must be careful not to overflow the actual space; this is often hard to assure. For safety, programmers should use the snprintf interface instead.
http://www.codecogs.com/reference/computing/c/stdio.h/printf.php?alias=snprintf

Glib has it's own safer version of sprintf() called g_snprintf().
Quote:
..output is guaranteed to not exceed n characters (including the terminating nul character), so it is easy to ensure that a buffer overflow cannot occur.
http://developer.gnome.org/glib/2.28/glib-String-Utility-Functions.html#g-snprintf

But to use it you'll have to explicitly include <glib/gprintf.h> as I mentioned in this post:
http://www.gtkforums.com/viewtopic.php?f=3&t=178125

As for the white spaces I believe you can use the format specifier: "%[^\n]"


Top
 Profile  
 
 Post subject: Re: sprintf a filename
PostPosted: Wed Sep 19, 2012 7:35 am 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 745
Location: UK
Hi,

Just to add more in terms of security. The system() function call can have security problems if you have built the command line up from what some of the input the user has provided. It maybe possible for the user to provide input that could execute other programs in addition to your own or cause additional problems with your application due to mangled data.

I would suggest that you use the Glib set of spawn functions instead. Although it looks fairly complicated at first you do end up with much more control over what happens and without the security problems of the command line shell if your user enters sometime nasty. In the example below all that happens is the file name would be invalid for a malicious input. You can make the code even more secure by specifying an absolute path for the executable and asking not to search all the PATH environment variable.

Documentation for g_spawn_sync() can be found at http://developer.gnome.org/glib/stable/glib-Spawning-Processes.html#g-spawn-sync
Code:

if (gtk_dialog_run(GTK_DIALOG(pdialog)) == GTK_RESPONSE_ACCEPT) {
        pdfname = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(pdialog));
    }
    gtk_entry_set_text(GTK_ENTRY(entrypdf), pdfname);

  {
    gchar *argv[3];
    gchar *result;

    argv[0] = "pdfinfo";
    argv[1] = pdfname;
    argv[2] = NULL;

    g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
        NULL, NULL, &result, NULL, NULL, NULL);

    /* Use the output which is now in the string result */

    /* Free the result */
    g_free(result);
  }

_________________
E.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: Yahoo [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group