ISO/ IEC JTC1/SC22/WG14 N1110

WG14 Document: N1110
Date: 2005-03-09
 
----------------------------------------------------------------------------------

Title: Overflow Protected String Building

Author: Peter van der Veen

Author Affiliation: QNX Software Systems Ltd.

Postal Address: 175 Terence Matthews Cr.

E-mail Address: peterv@qnx.com

Telephone Number: +1 613 591-0931

Fax Number: +1 613 591-3579

Sponsor:

Date: March 9, 2005

Document History: New proposal based on on-line discussion about Secure C Functions

Proposal Category:

  X  New API

Area of standard Affected:

  X  Language

Prior Art: QNX Neutrino (A real-time POSIX operating system)

Target Audience: programmers who need to safely build strings

Proposal Attached: X Yes

Abstract:

  The straddstr() function adds str to the buffer pointed to by pbuf, respecting the 
  maximum length indicated by pmaxbuf. The values of pbuf and pmaxlen are 
  updated.

Proposal:

  straddstr() - Concatenate one string on to the end of another

  Synopsis:

    #include <string.h>

    int straddstr(const char *str, int len, char **pbuf, size_t *pmaxbuf);

  Arguments:

    str - The string that you want to add to the end of another.

    len - The number of characters from str that you want to add. If zero, the 
    function adds all of str.

    pbuf - The address of a pointer to the destination buffer that will be updated.

    pmaxbuf - A pointer to the size of the destination buffer that will be updated.

  Library:

    libc

  Description:

    The straddstr function copies not more than the minimum of the size_t that 
    pmaxbuf points to or len successive characters (characters that follow a null 
    character are not copied) from the array pointed to by the character pointer 
    that pbuf points to. The character pointer that pbuf points to will be updated 
    to point to the end of the actual copied characters and the size_t that 
    pmaxbuf points to will be decremented by the actual copied characters. 
    The returned value is the number of characters in the passed in str even
    if the number of actual characters was less. If size_t that pmaxbuf points
    to was greater than zero on entring the function, then the character that is 
    pointed to by the character pointer pbuf will always be ‘\0’ on return. If len 
    was passed in as a 0 then the length is calculated as if strlen was called
    on str.

  Example:

    This function can be called many consecutivly to safely build a string. The string 
    will always be null terminated even if the source strings do not fit into the destination 
    buffer.

    #include <string.h>

    /* ... */

    int myfunc(char *buf, size_t bufsize) {

      int len = straddstr("string1", 0, &buf, &bufsize);

      len += straddstr("string2?????", 7, &buf, &bufsize);

      len += straddstr("string3", 10, &buf, &bufsize);

      return len;

    }

    /* ... */

       char buf1[10], buf2[100];

       int len1 = myfunc(buf1, sizeof buf1);

       int len2 = myfunc(buf2, sizeof buf2);

   

    In the example the myfunc function will always return 21, the desired size of the buffer
    to contain all of the strings, but the buffer will only contain up to bufsiz-1 of the 
    character strings always terminating resulting string with a ‘\0’ character. In this 
    example len1 == len2 == 21 and buf1 will contain "string1st\0" and buf2 will contain 
    "string1string2string3\0???...???" where the characters after the ‘\0’ are not touched.

    The values of buf and bufsize in the first invocation of myfunc() with an original size 
    of 10 would be

      before:      &original_buf[0]    bufsize=10

      after 1st:   &original_buf[7]    bufsize=3

      after 2nd:   &original_buf[9]    bufsize=1

      after 3rd:   &original_buf[9]    bufsize=1

    The values of buf and bufsize in the second invocation of myfunc() with an original 
    size of 100 would be

      before:      &original_buf[0]    bufsize=100

      after 1st:   &original_buf[7]    bufsize=93

      after 2nd:   &original_buf[14]   bufsize=86

      after 3rd:   &original_buf[21]   bufsize=79

  Returns:

    The value of len if it's nonzero; otherwise, the length of str (i.e. strlen(str)).