sprintf() unstable?

This is a discussion on sprintf() unstable? within the C Programming forums, part of the General Programming Boards category; I've been hearing that sprintf() is an unstable function, and that there is a better function that does the same. ...

  1. #1
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768

    sprintf() unstable?

    I've been hearing that sprintf() is an unstable function, and that there is a better function that does the same.

    Anyone knows anything about that?




    Thank you.
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    sprintf is dangerous because buffer overflows are so easy to create. It's also error prone because the solution to the buffer overflow problem is complex. The function you've been hearing about is probably some version of snprintf, but snprintf is only standard in C99. Otherwise it's an implementation-defined extension.
    My best code is written with the delete key.

  3. #3
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    so what can I use instead sprintf() in C95?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >so what can I use instead sprintf() in C95?
    If you want to remain standard and portable then you really have no choice but to use sprintf unless you want to perform the conversions it makes manually. You can overcome the safety issues like so:
    Code:
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    char *make_str(const char *fmt, ...);
    
    int
    main(void)
    {
      char   *str;
    
      str = make_str("%f:%d -- %s", 123.456, 10, "testing");
      printf("%s\n", str);
      free(str);
    
      return 0;
    }
    
    char *
    make_str(
      const char *fmt,
      ...
      )
    {
      FILE    *temp = tmpfile();
      va_list  args;
      char    *str;
      int      size;
    
      /*
        Calculate the string size by
        writing to a scratch file.
      */
      if (!temp) {
        return NULL;
      }
      va_start(args, fmt);
      size = vfprintf(temp, fmt, args);
      va_end(args);
      fclose(temp);
      /*
        Create the buffer
      */
      if (size < 1) {
        return NULL;
      }
      str = malloc(size + 1);
      if (!str) {
        return NULL;
      }
      /*
        Write to the correctly sized buffer
      */
      va_start(args, fmt);
      vsprintf(str, fmt, args);
      va_end(args);
    
      return str;
    }
    It's godawful hackish, but sometimes you gotta do what you gotta do. The only real problems with this approach are that it's slow (writing to a temporary file) and you return memory that must be freed (effectively guaranteeing that it won't be ). But it's general and handles the problems quite elegantly.
    My best code is written with the delete key.

  5. #5
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    If you want to remain standard and portable then you really have no choice but to use sprintf
    How big is the buffer overflow problem with sprintf, does it create a big security hole?
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    >How big is the buffer overflow problem with sprintf
    If you're careful about making your buffers the right size then the problem isn't very big.

    >does it create a big security hole?
    It can if you don't have control over the arguments and your buffer is of a fixed size. That's why the only safe use of sprintf is to calculate the total size of all of the arguments plus any extra characters in the format string (and a null character ), then malloc a buffer of the right size. If you don't do that at some point before calling sprintf, you risk a buffer overflow.
    My best code is written with the delete key.

  7. #7
    * Death to Visual Basic * Devil Panther's Avatar
    Join Date
    Aug 2001
    Posts
    768
    So what you're saying is always to keep track of inputs from the user, and allocate using that total size.
    there is no risk for heap overflow, right?!
    "I don't suffer from insanity but enjoy every minute of it" - Edgar Allen Poe

    http://www.Bloodware.net - Developing free software for the community.

  8. #8
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Just use snprintf followed by explicit nul termination. In the rare case that a platform doesn't have an implementation of snprintf, a solution like posted by Prelude can be used to provide one.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sprintf overflows my buffer -- why?
    By Lasston in forum C Programming
    Replies: 26
    Last Post: 06-20-2008, 04:33 PM
  2. sprintf : garbage appended
    By yeller in forum C Programming
    Replies: 9
    Last Post: 12-17-2007, 09:21 AM
  3. sprintf Wrapping, a tough one
    By AdmiralKirk in forum C++ Programming
    Replies: 3
    Last Post: 02-03-2006, 09:43 AM
  4. sprintf and sscanf
    By tommy69 in forum C Programming
    Replies: 10
    Last Post: 04-22-2004, 08:00 PM
  5. Sprintf
    By Trauts in forum C++ Programming
    Replies: 10
    Last Post: 01-15-2003, 12:35 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21