ISO/ IEC JTC1/SC22/WG14 N645

                     Document Number:  WG14 N645/X3J11 96-008


                        C9X Revision Proposal
                        =====================

Title: Alternative to sprintf
Author: Douglas A. Gwyn
Author Affiliation: United States Army Research Laboratory
Postal Address: 801-L Cashew Court, Bel Air, MD 21014, USA
E-mail Address: gwyn@arl.mil
Telephone Number: +1 410-278-8945
Fax Number: +1 410-278-2934
Original Author: Keith Bostic
Author Affiliation: University of California, Berkeley
Postal Address: 394 East Riding Dr., Carlisle, MA 01741, USA
E-mail Address: bostic@cs.berkeley.edu
Telephone Number: +1 508-287-4781
Fax Number:
Sponsor: X3J11
Date: 1997-01-03
Document History:  1995-05-17 WG14/N430 & X3J11/95-031
        (original proposal from Bostic) received a favorable
        response from WG14, but further development was
        suggested; Gwyn volunteered to champion the issue,
        and 1996-09-13 WG14 N614/X3J11 96-078 was the result.
        At the Toronto meeting, the committee expressed a
        desire to allow buffer size of 0 and also (in such a
        case) to allow a null buffer pointer; wording for
        this was approved near the end of that meeting, and
        the present document contains that wording.  This
        will be subject to a final editorial review before
        the indicated changes are made to the C9x draft.
Proposal Category:
   __ Editorial change/non-normative contribution
   __ Correction
   x_ New feature
   __ Addition to obsolescent feature list
   __ Addition to Future Directions
   __ Other (please specify)
Area of Standard Affected:
   __ Environment
   __ Language
   __ Preprocessor
   x_ Library
      __ Macro/typedef/tag name
      x_ Function
      x_ Header
   __ Other (please specify)
Prior Art: 4.4BSD snprintf and Plan 9 snprint functions
Target Audience: all C programmers
Related Documents (if any): C89 7.9.6.5 and 7.9.6.9
Proposal Attached: x_ Yes __ No, but what's your interest?
Abstract: The current sprintf function and the closely
        related vsprintf function are very useful, but
        can overrun the output buffer.  This behavior has
        been exploited in various attacks on computer and
        network security.  A version that performs bounds
        checking is highly desirable; such implementations
        do exist, and standardization of this facility
        would be helpful in producing portable robust code.

Proposal: The intent is to add functions analogous to the
        existing sprintf and vsprintf (which would continue
        to be specified in C9x, since existing strictly
        conforming code depends on them), that add bounds
        checking but otherwise act the same as the existing
        functions.

        Add new subsection after 7.10.6.5 The sprintf function:

                7.10.6.5-and-a-half The snprintf function

                Synopsis

                        #include <stdio.h>
                        int snprintf(char * restrict s, size_t n,
                                const char * restrict format,
                                ...);

                Description

                The snprintf function is equivalent to fprintf,
                except that the argument s specifies an array
                into which the generated output is to be written,
                rather than to a stream.  If n is zero, nothing
                is written, and s may be a null pointer.
                Otherwise, output characters beyond the n-1st are
                discarded rather than being written to the array,
                and a null character is written at the end of the
                characters actually written into the array.  If
                copying takes place between objects that overlap,
                the behavior is undefined.

                Returns

                The snprintf function returns the number of
                characters that would have been written had n
                been sufficiently large, not counting the
                terminating null character.  Thus, the null-
                terminated output has been completely written if
                and only if the returned value is less than n.

        Add new subsection after 7.10.6.9 The vsprintf function:


                7.10.6.9-and-a-half The vsnprintf function

                Synopsis

                        #include <stdarg.h>
                        #include <stdio.h>
                        int vsnprintf(char * restrict s, size_t n,
                                const char * restrict format,
                                va_list arg);

                Description

                The vsnprintf function is equivalent to
                snprintf, with the variable argument list
                replaced by arg, which shall have been
                initialized by the va_start macro (and possibly
                subsequent va_arg calls).  The vsnprintf function
                does not invoke the va_end macro [MODIFIED
                FOOTNOTE 136:  As the functions vfprintf,
                vsprintf, vnsprintf, and vprintf invoke the
                va_arg macro, the value of arg after the return
                is indeterminate.]  If copying takes place
                between objects that overlap, the behavior is
                undefined.

                Returns

                The vsnprintf function returns the number of
                characters that would have been written had n
                been sufficiently large, not counting the
                terminating null character.  Thus, the null-
                terminated output has been completely written if
                and only if the returned value is less than n.

        (I realize that this breaks the alphabetic order of
        the subsections, but logical ordering is more important.
        The Redactor will, of course, have to renumber the
        subsections after 7.10.6.5 to avoid using halves.)

        In the Rationale document, the new subsection after
        7.10.6.5 should read:

                7.10.6.5-and-a-half The snprintf function

                The sprintf function is very useful, but
                can overrun the output buffer; that has been
                exploited in attacks on computer and network
                security.  C9x addresses this problem by adding
                the snprintf function, modeled after the 4.4BSD
                version, which performs bounds checking on the
                output array.

        There might be just a heading for 7.10.6.9-and-a-half
        in the Rationale document, with no explanatory text,
        if so dictated by the final document style:

                7.10.6.9-and-a-half The vsnprintf function