Document Number: WG14 N614/X3J11 96-078 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: 1996-09-13 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 this is the revised proposal. 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.9.6.5 The sprintf function: 7.9.6.5-and-a-half The snprintf function Synopsis #include int snprintf(char *s, size_t n, const char *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. Output characters beyond the n-1st are discarded rather than being written to the array. 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, output has been discarded if and only if the returned value is n or more. Add new subsection after 7.9.6.9 The vsprintf function: 7.9.6.9-and-a-half The vsnprintf function Synopsis #include #include int vsnprintf(char *s, size_t n, const char *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, output has been discarded if and only if the returned value is n or more. (I realize that this breaks the alphabetic order of the subsections. Logical ordering is more important.) In the Rationale document, the new subsection after 7.9.6.5 should read: 7.9.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.