* pvsnprintf * * Attempt to format text data under the control of fmt (an sprintf-style * format string) and insert it into buf (which has length len). * * If successful, return the number of bytes emitted, not counting the * trailing zero byte. This will always be strictly less than len. * * If there's not enough space in buf, return an estimate of the buffer size * needed to succeed (t
| 103 | * this lets overflow concerns be handled here rather than in the callers. |
| 104 | */ |
| 105 | size_t |
| 106 | pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) |
| 107 | { |
| 108 | int nprinted; |
| 109 | |
| 110 | nprinted = vsnprintf(buf, len, fmt, args); |
| 111 | |
| 112 | /* We assume failure means the fmt is bogus, hence hard failure is OK */ |
| 113 | if (unlikely(nprinted < 0)) |
| 114 | { |
| 115 | #ifndef FRONTEND |
| 116 | elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt); |
| 117 | #else |
| 118 | fprintf(stderr, "vsnprintf failed: %s with format string \"%s\"\n", |
| 119 | strerror(errno), fmt); |
| 120 | exit(EXIT_FAILURE); |
| 121 | #endif |
| 122 | } |
| 123 | |
| 124 | if ((size_t) nprinted < len) |
| 125 | { |
| 126 | /* Success. Note nprinted does not include trailing null. */ |
| 127 | return (size_t) nprinted; |
| 128 | } |
| 129 | |
| 130 | /* |
| 131 | * We assume a C99-compliant vsnprintf, so believe its estimate of the |
| 132 | * required space, and add one for the trailing null. (If it's wrong, the |
| 133 | * logic will still work, but we may loop multiple times.) |
| 134 | * |
| 135 | * Choke if the required space would exceed MaxAllocSize. Note we use |
| 136 | * this palloc-oriented overflow limit even when in frontend. |
| 137 | */ |
| 138 | if (unlikely((size_t) nprinted > MaxAllocSize - 1)) |
| 139 | { |
| 140 | #ifndef FRONTEND |
| 141 | ereport(ERROR, |
| 142 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
| 143 | errmsg("out of memory"))); |
| 144 | #else |
| 145 | fprintf(stderr, _("out of memory\n")); |
| 146 | exit(EXIT_FAILURE); |
| 147 | #endif |
| 148 | } |
| 149 | |
| 150 | return nprinted + 1; |
| 151 | } |
no test coverage detected