LCOV - code coverage report
Current view: top level - Python - mysnprintf.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 16 18 88.9 %
Date: 2022-07-07 18:19:46 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "Python.h"
       2             : 
       3             : /* snprintf() and vsnprintf() wrappers.
       4             : 
       5             :    If the platform has vsnprintf, we use it, else we
       6             :    emulate it in a half-hearted way.  Even if the platform has it, we wrap
       7             :    it because platforms differ in what vsnprintf does in case the buffer
       8             :    is too small:  C99 behavior is to return the number of characters that
       9             :    would have been written had the buffer not been too small, and to set
      10             :    the last byte of the buffer to \0.  At least MS _vsnprintf returns a
      11             :    negative value instead, and fills the entire buffer with non-\0 data.
      12             : 
      13             :    The wrappers ensure that str[size-1] is always \0 upon return.
      14             : 
      15             :    PyOS_snprintf and PyOS_vsnprintf never write more than size bytes
      16             :    (including the trailing '\0') into str.
      17             : 
      18             :    Return value (rv):
      19             : 
      20             :     When 0 <= rv < size, the output conversion was unexceptional, and
      21             :     rv characters were written to str (excluding a trailing \0 byte at
      22             :     str[rv]).
      23             : 
      24             :     When rv >= size, output conversion was truncated, and a buffer of
      25             :     size rv+1 would have been needed to avoid truncation.  str[size-1]
      26             :     is \0 in this case.
      27             : 
      28             :     When rv < 0, "something bad happened".  str[size-1] is \0 in this
      29             :     case too, but the rest of str is unreliable.  It could be that
      30             :     an error in format codes was detected by libc, or on platforms
      31             :     with a non-C99 vsnprintf simply that the buffer wasn't big enough
      32             :     to avoid truncation, or on platforms without any vsnprintf that
      33             :     PyMem_Malloc couldn't obtain space for a temp buffer.
      34             : 
      35             :    CAUTION:  Unlike C99, str != NULL and size > 0 are required.
      36             :    Also, size must be smaller than INT_MAX.
      37             : */
      38             : 
      39             : int
      40     1374220 : PyOS_snprintf(char *str, size_t size, const  char  *format, ...)
      41             : {
      42             :     int rc;
      43             :     va_list va;
      44             : 
      45     1374220 :     va_start(va, format);
      46     1374220 :     rc = PyOS_vsnprintf(str, size, format, va);
      47     1374220 :     va_end(va);
      48     1374220 :     return rc;
      49             : }
      50             : 
      51             : int
      52     1378600 : PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va)
      53             : {
      54     1378600 :     assert(str != NULL);
      55     1378600 :     assert(size > 0);
      56     1378600 :     assert(size <= (INT_MAX - 1));
      57     1378600 :     assert(format != NULL);
      58             : 
      59             :     int len;  /* # bytes written, excluding \0 */
      60             :     /* We take a size_t as input but return an int.  Sanity check
      61             :      * our input so that it won't cause an overflow in the
      62             :      * vsnprintf return value.  */
      63     1378600 :     if (size > INT_MAX - 1) {
      64           0 :         len = -666;
      65           0 :         goto Done;
      66             :     }
      67             : 
      68             : #if defined(_MSC_VER)
      69             :     len = _vsnprintf(str, size, format, va);
      70             : #else
      71     1378600 :     len = vsnprintf(str, size, format, va);
      72             : #endif
      73             : 
      74     1378600 : Done:
      75     1378600 :     if (size > 0) {
      76     1378600 :         str[size-1] = '\0';
      77             :     }
      78     1378600 :     return len;
      79             : }

Generated by: LCOV version 1.14