| OLD | NEW |
| 1 #include "stdio_impl.h" | 1 #include "stdio_impl.h" |
| 2 #include <limits.h> | 2 #include <limits.h> |
| 3 #include <string.h> | 3 #include <string.h> |
| 4 #include <errno.h> | 4 #include <errno.h> |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 static size_t sn_write(FILE *f, const unsigned char *s, size_t l) | 7 static size_t sn_write(FILE* f, const unsigned char* s, size_t l) { |
| 8 { | 8 size_t k = f->wend - f->wpos; |
| 9 » size_t k = f->wend - f->wpos; | 9 if (k > l) |
| 10 » if (k > l) k = l; | 10 k = l; |
| 11 » memcpy(f->wpos, s, k); | 11 memcpy(f->wpos, s, k); |
| 12 » f->wpos += k; | 12 f->wpos += k; |
| 13 » /* pretend to succeed, but discard extra data */ | 13 /* pretend to succeed, but discard extra data */ |
| 14 » return l; | 14 return l; |
| 15 } | 15 } |
| 16 | 16 |
| 17 int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) | 17 int vsnprintf(char* restrict s, |
| 18 { | 18 size_t n, |
| 19 » int r; | 19 const char* restrict fmt, |
| 20 » char b; | 20 va_list ap) { |
| 21 » FILE f = { .lbf = EOF, .write = sn_write, .lock = -1 }; | 21 int r; |
| 22 char b; |
| 23 FILE f = {.lbf = EOF, .write = sn_write, .lock = -1}; |
| 22 | 24 |
| 23 » if (n-1 > INT_MAX-1) { | 25 if (n - 1 > INT_MAX - 1) { |
| 24 » » if (n) { | 26 if (n) { |
| 25 » » » errno = EOVERFLOW; | 27 errno = EOVERFLOW; |
| 26 » » » return -1; | 28 return -1; |
| 27 » » } | 29 } |
| 28 » » s = &b; | 30 s = &b; |
| 29 » » n = 1; | 31 n = 1; |
| 30 » } | 32 } |
| 31 | 33 |
| 32 » /* Ensure pointers don't wrap if "infinite" n is passed in */ | 34 /* Ensure pointers don't wrap if "infinite" n is passed in */ |
| 33 » if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1; | 35 if (n > (char*)0 + SIZE_MAX - s - 1) |
| 34 » f.buf_size = n; | 36 n = (char*)0 + SIZE_MAX - s - 1; |
| 35 » f.buf = f.wpos = (void *)s; | 37 f.buf_size = n; |
| 36 » f.wbase = f.wend = (void *)(s+n); | 38 f.buf = f.wpos = (void*)s; |
| 37 » r = vfprintf(&f, fmt, ap); | 39 f.wbase = f.wend = (void*)(s + n); |
| 40 r = vfprintf(&f, fmt, ap); |
| 38 | 41 |
| 39 » /* Null-terminate, overwriting last char if dest buffer is full */ | 42 /* Null-terminate, overwriting last char if dest buffer is full */ |
| 40 » if (n) f.wpos[-(f.wpos == f.wend)] = 0; | 43 if (n) |
| 41 » return r; | 44 f.wpos[-(f.wpos == f.wend)] = 0; |
| 45 return r; |
| 42 } | 46 } |
| OLD | NEW |